From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 04:30:47 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 46B00106566C for ; Sun, 15 Jan 2012 04:30:47 +0000 (UTC) (envelope-from bnorton916@yahoo.com) Received: from nm28-vm2.bullet.mail.ne1.yahoo.com (nm28-vm2.bullet.mail.ne1.yahoo.com [98.138.91.128]) by mx1.freebsd.org (Postfix) with SMTP id EF5D08FC08 for ; Sun, 15 Jan 2012 04:30:46 +0000 (UTC) Received: from [98.138.90.52] by nm28.bullet.mail.ne1.yahoo.com with NNFMP; 15 Jan 2012 04:17:21 -0000 Received: from [98.138.89.250] by tm5.bullet.mail.ne1.yahoo.com with NNFMP; 15 Jan 2012 04:17:21 -0000 Received: from [127.0.0.1] by omp1042.mail.ne1.yahoo.com with NNFMP; 15 Jan 2012 04:17:21 -0000 X-Yahoo-Newman-Property: ymail-3 X-Yahoo-Newman-Id: 746072.48120.bm@omp1042.mail.ne1.yahoo.com Received: (qmail 18185 invoked by uid 60001); 15 Jan 2012 04:17:21 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1326601041; bh=fNBdTnkwITGhGX2WMj1AE9JOTg/QF+pRjaW9+nGfmkQ=; h=X-YMail-OSG:Received:X-Mailer:References:Message-ID:Date:From:Reply-To:Subject:To:Cc:In-Reply-To:MIME-Version:Content-Type; b=hE2Pl2+iLuqHCBVK1baqXIXK/V3A/s0d1f4EnhEH4Vih/LUHGgy9ueUycXpGXpfwiMorrS36+4O2UMwXEmTEhJXtKfNUdmuATNaf+WVO6M3xMIZIXfkhXHGAbLa+/abr38Pn8y9xOzKJ3/wmjFJw+Ub15Bb2iOr1bpoa9ioILrc= DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=X-YMail-OSG:Received:X-Mailer:References:Message-ID:Date:From:Reply-To:Subject:To:Cc:In-Reply-To:MIME-Version:Content-Type; b=imeQy97d3uIyHbM2qfborV8/WLJ9iPJkA7DB4d/jw3QYkq1PAi97V4rouMgpG5n7Sl6KyzCySawzrAj3vD2VGCEQI4yhB3P0dOKzjanOwTszrOph66V7dvtO1smtfM9yKaD/E2obRQ1LVRaSmg4wRg6ntnXcQmVeFjUOI16OBIc=; X-YMail-OSG: pbapquAVM1mpDRFPXA03YyK.X45DS3MMBD.eWSYb2FvbFd8 36Sk7czaOkZogfoB49fjfsLxxlH0wx7QAi9bqg9GRuI20yPT6ELc9Gws3i4B B2JlXcBLRjAu_OwME078n4w8_Qel5KXWjnKpKDF5yY9YxOguafbTUt9AFDac XAyvQBNxsVgp9mUWufvik29f03IoWIKrQmXSq0xeb42p29y0IDxarHO1oRrL j21oWLbBC.QR2YWz.m4YC5CPZteLPll2tymLhbgoJeSlafoDYSPA7Eae2S8Z .Ug2zkkZNxJ78z.4ZKZYetgc1FtubfAdX2mtA9obU1W9HAeZaSVePZsh2Mtb 3iymdtM.9tfhup8_AHklKjURA.pyvJc_oucNtZ3cdXEdZ7ORqpEJ0ee4ahTD .8G0K.IYY1B5trX4XWizEAe4QlGi9YHIox1sz74S0KXFU71lQeGRkO9egMH1 V1XnRpG1h3eSmSs9QT3Xiz9M- Received: from [96.38.98.89] by web36504.mail.mud.yahoo.com via HTTP; Sat, 14 Jan 2012 20:17:21 PST X-Mailer: YahooMailWebService/0.8.115.331698 References: <1326560151.30035.YahooMailNeo@web36505.mail.mud.yahoo.com> <20120114225358.GA22889@michelle.cdnetworks.com> Message-ID: <1326601041.94506.YahooMailNeo@web36504.mail.mud.yahoo.com> Date: Sat, 14 Jan 2012 20:17:21 -0800 (PST) From: Bill Norton To: "pyunyh@gmail.com" In-Reply-To: <20120114225358.GA22889@michelle.cdnetworks.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: "freebsd-net@freebsd.org" , "jhb@FreeBSD.org" Subject: Re: bge0 interface seen but not working X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Bill Norton List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 04:30:47 -0000 Thanks, adding the line made a difference.=A0=0ADHCP did not seem to work(I= received an address(which I didn't before adding the loader.conf) but coul= dn't ping the DHCP server).=0AWhen I set the bge0 interface to a static add= ress everything started working.=0A=0AI didn't fully test the DHCP out thou= gh.=0A=0AI=A0appreciate=A0you helping out on this.=0A=0AThank you,=0A=0ABil= l Norton=0A=0A=0A________________________________=0A From: YongHyeon PYUN <= pyunyh@gmail.com>=0ATo: Bill Norton =0ACc: "freebsd-= net@freebsd.org" ; jhb@FreeBSD.org =0ASent: Saturd= ay, January 14, 2012 5:53 PM=0ASubject: Re: bge0 interface seen but not wor= king=0A =0AOn Sat, Jan 14, 2012 at 08:55:51AM -0800, Bill Norton wrote:=0A>= Greetings,=0A> =0A> I posted this on the pc-bsd forum and was directed her= e.?=0A> =0A> I installed the latest 8.X and the interface worked fine.?=0A>= =0A> Yesterday, I did a clean install of 9.0.?=0A> =0A> The issue is that = the bge0 interface is not working.?=0A> It is seen by the kernel(ifconfig s= hows it) but just won't ping.=0A> I have tried dhcp and a static address.?= =0A> I used a backtrack live cd and this worked fine.?=0A> =0A=0AProbably d= isabling MSI will workaround your issue. Add=0A=0Ahw.pci.enable_msi=3D"0"= =0A=0Ato /boot/loader.conf.=0A=0A> =0A> I did find this bug below but it se= emed to only affect 8.2=0A> =0A> The bge(4) Ethernet driver has a known iss= ue where the interface is seen but does not respond to networking requests.= A patch is available for 8.2 (see 155442) and the driver will be fixed in = 8.3.=0A> =0A> Any ideas??=0A> =0A=0AI thought it was already fixed by John = but it seems it is not.=0AJohn, would you take a look?(NVIDIA HT MSI issue)= ? From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 18:50:33 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A86511065673 for ; Sun, 15 Jan 2012 18:50:33 +0000 (UTC) (envelope-from andrey@zonov.org) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id 397588FC08 for ; Sun, 15 Jan 2012 18:50:32 +0000 (UTC) Received: by bke11 with SMTP id 11so893807bke.13 for ; Sun, 15 Jan 2012 10:50:32 -0800 (PST) Received: by 10.205.37.198 with SMTP id tf6mr3546391bkb.68.1326652031806; Sun, 15 Jan 2012 10:27:11 -0800 (PST) Received: from [10.254.254.77] (ppp95-165-126-65.pppoe.spdop.ru. [95.165.126.65]) by mx.google.com with ESMTPS id n9sm33704033bkg.8.2012.01.15.10.27.10 (version=SSLv3 cipher=OTHER); Sun, 15 Jan 2012 10:27:11 -0800 (PST) Message-ID: <4F131A7D.4020006@zonov.org> Date: Sun, 15 Jan 2012 22:27:09 +0400 From: Andrey Zonov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.24) Gecko/20100228 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: Nikolay Denev References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: ICMP attacks against TCP and PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 18:50:33 -0000 Hi, Could you please show the output of `vmstat -z | grep hostcache'? On 12.01.2012 21:55, Nikolay Denev wrote: > Hello, > > A web server that I administer running Nginx and FreeBSD-7.3-STABLE was recently > under a ICMP attack that generated a large amount of outgoing TCP traffic. > With some tcpdump and netflow analysis it was evident that the attachers are using > ICMP host-unreach need-frag messages to make the web server > retransmit multiple times, giving a amplification factor of about 1.6. > Then I noticed RFC5927 ( http://www.faqs.org/rfcs/rfc5927.html ) and specifically section 7.2 > which discusses countermeasures against such attacks. The text reads : > > This section describes a modification to the PMTUD mechanism > specified in [RFC1191] and [RFC1981] that has been incorporated in > OpenBSD and NetBSD (since 2005) to improve TCP's resistance to the > blind performance-degrading attack described in Section 7.1. The > described counter-measure basically disregards ICMP messages when a > connection makes progress, without violating any of the requirements > stated in [RFC1191] and [RFC1981]. > > The RFC is recent (dated from July 2010), and it mentions several times Linux, Free,Open and NetBSD, > but exactly in this paragraph it is mentioning only Net and OpenBSD's, thus I'm asking if > anyone has idea if these modifications were being put into FreeBSD? > > I quickly glanced upon the source, but the TCP code is a bit too much for me :) > > Also if anybody has observed similar attack, how are you protecting yourself from it? > Simply blocking host-unreach need-frag would break PMTUD. > > P.S.: I know 7.3 is pretty old, and I've planned upgrade to 8.2. I'm also curious if 8.2 will behave differently. > > Regards, > Nikolay > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" -- Andrey Zonov From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 18:59:38 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C60B1065678 for ; Sun, 15 Jan 2012 18:59:38 +0000 (UTC) (envelope-from ndenev@gmail.com) Received: from mail-ee0-f54.google.com (mail-ee0-f54.google.com [74.125.83.54]) by mx1.freebsd.org (Postfix) with ESMTP id 9E1538FC08 for ; Sun, 15 Jan 2012 18:59:37 +0000 (UTC) Received: by eeke53 with SMTP id e53so1214005eek.13 for ; Sun, 15 Jan 2012 10:59:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=subject:mime-version:content-type:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to:x-mailer; bh=8ZK9YnQDD7MKgplb35J4y7hlaK/kgrJpkAGHnB6s5mg=; b=w/rh45orY8FUMH/1P2Bm/gvWuOru48EckWQDXjuwBTFN5WF4PbDfOSQ9BB1UUrOxFO wAetarKSH35Gb4d3QBnC6I1ULCXTiPHCVQEjArC4UY+xlKHC4ZZGRkWNrWmVL3PY+jb8 zf5PGgXcaMwxOm9vyeN29EYeU/RSpY8XkOuOw= Received: by 10.213.35.4 with SMTP id n4mr2780472ebd.85.1326653976373; Sun, 15 Jan 2012 10:59:36 -0800 (PST) Received: from imba-brutale.totalterror.net (93-152-152-135.ddns.onlinedirect.bg. [93.152.152.135]) by mx.google.com with ESMTPS id 76sm62001807eeh.0.2012.01.15.10.59.33 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 15 Jan 2012 10:59:35 -0800 (PST) Mime-Version: 1.0 (Apple Message framework v1251.1) Content-Type: text/plain; charset=windows-1252 From: Nikolay Denev In-Reply-To: <4F131A7D.4020006@zonov.org> Date: Sun, 15 Jan 2012 20:59:32 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <733BE6AF-33E0-4C16-A222-B5F5D0519194@gmail.com> References: <4F131A7D.4020006@zonov.org> To: Andrey Zonov X-Mailer: Apple Mail (2.1251.1) Cc: freebsd-net@freebsd.org Subject: Re: ICMP attacks against TCP and PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 18:59:38 -0000 On Jan 15, 2012, at 8:27 PM, Andrey Zonov wrote: > Hi, >=20 > Could you please show the output of `vmstat -z | grep hostcache'? >=20 > On 12.01.2012 21:55, Nikolay Denev wrote: >> Hello, >>=20 >> A web server that I administer running Nginx and FreeBSD-7.3-STABLE = was recently >> under a ICMP attack that generated a large amount of outgoing TCP = traffic. >> With some tcpdump and netflow analysis it was evident that the = attachers are using >> ICMP host-unreach need-frag messages to make the web server >> retransmit multiple times, giving a amplification factor of about = 1.6. >> Then I noticed RFC5927 ( http://www.faqs.org/rfcs/rfc5927.html ) and = specifically section 7.2 >> which discusses countermeasures against such attacks. The text reads = : >>=20 >> This section describes a modification to the PMTUD mechanism >> specified in [RFC1191] and [RFC1981] that has been incorporated in >> OpenBSD and NetBSD (since 2005) to improve TCP's resistance to the >> blind performance-degrading attack described in Section 7.1. The >> described counter-measure basically disregards ICMP messages when = a >> connection makes progress, without violating any of the = requirements >> stated in [RFC1191] and [RFC1981]. >>=20 >> The RFC is recent (dated from July 2010), and it mentions several = times Linux, Free,Open and NetBSD, >> but exactly in this paragraph it is mentioning only Net and = OpenBSD's, thus I'm asking if >> anyone has idea if these modifications were being put into FreeBSD? >>=20 >> I quickly glanced upon the source, but the TCP code is a bit too much = for me :) >>=20 >> Also if anybody has observed similar attack, how are you protecting = yourself from it? >> Simply blocking host-unreach need-frag would break PMTUD. >>=20 >> P.S.: I know 7.3 is pretty old, and I've planned upgrade to 8.2. I'm = also curious if 8.2 will behave differently. >>=20 >> Regards, >> Nikolay >>=20 >> _______________________________________________ >> freebsd-net@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-net >> To unsubscribe, send any mail to = "freebsd-net-unsubscribe@freebsd.org" >=20 > --=20 > Andrey Zonov % uptime=20 7:57PM up 608 days, 4:06, 1 user, load averages: 0.30, 0.21, 0.17 % vmstat -z|grep hostcache hostcache: 136, 15372, 15136, 236, 44946965, = 10972760 Hmm=85 probably I should increase this=85. From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 19:17:52 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 10B59106566C for ; Sun, 15 Jan 2012 19:17:52 +0000 (UTC) (envelope-from andrey@zonov.org) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id 9704C8FC0C for ; Sun, 15 Jan 2012 19:17:51 +0000 (UTC) Received: by bke17 with SMTP id 17so13807bke.13 for ; Sun, 15 Jan 2012 11:17:50 -0800 (PST) Received: by 10.204.151.69 with SMTP id b5mr3721294bkw.14.1326655070429; Sun, 15 Jan 2012 11:17:50 -0800 (PST) Received: from [10.254.254.77] (ppp95-165-126-65.pppoe.spdop.ru. [95.165.126.65]) by mx.google.com with ESMTPS id ek9sm3208376bkb.10.2012.01.15.11.17.49 (version=SSLv3 cipher=OTHER); Sun, 15 Jan 2012 11:17:50 -0800 (PST) Message-ID: <4F13265C.1040200@zonov.org> Date: Sun, 15 Jan 2012 23:17:48 +0400 From: Andrey Zonov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.24) Gecko/20100228 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: em loses link after IPMI reset X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 19:17:52 -0000 Hi, I have a few boxes with Intel 82574L NIC that run under 8.2-STABLE. After execution `ipmitool mc reset cold' NIC loses link and after negotiation it sets 100TX media type (normal is 1000T). Under Linux on the same box this problem doesn't occur, after BMC reset driver doesn't lose link. It seems that em driver sets (or doesn't set) some IPMI relied registers. In Linux there is some magic about 82574/82583 chips and IPMI [1]. What do you think this is a solution for my problem or this is about something else? [1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/net/ethernet/intel/e1000e/netdev.c;h=3911401ed65d59ceafe9b28080a6630f4adf6371;hb=HEAD#l2696 -- Andrey Zonov From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 19:35:22 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A642D106566C for ; Sun, 15 Jan 2012 19:35:22 +0000 (UTC) (envelope-from andrey@zonov.org) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id 2F0688FC26 for ; Sun, 15 Jan 2012 19:35:21 +0000 (UTC) Received: by bke17 with SMTP id 17so23921bke.13 for ; Sun, 15 Jan 2012 11:35:21 -0800 (PST) Received: by 10.204.131.65 with SMTP id w1mr3582859bks.101.1326656121060; Sun, 15 Jan 2012 11:35:21 -0800 (PST) Received: from [10.254.254.77] (ppp95-165-126-65.pppoe.spdop.ru. [95.165.126.65]) by mx.google.com with ESMTPS id a17sm34049983bkz.7.2012.01.15.11.35.20 (version=SSLv3 cipher=OTHER); Sun, 15 Jan 2012 11:35:20 -0800 (PST) Message-ID: <4F132A76.6010501@zonov.org> Date: Sun, 15 Jan 2012 23:35:18 +0400 From: Andrey Zonov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.24) Gecko/20100228 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: Nikolay Denev References: <4F131A7D.4020006@zonov.org> <733BE6AF-33E0-4C16-A222-B5F5D0519194@gmail.com> In-Reply-To: <733BE6AF-33E0-4C16-A222-B5F5D0519194@gmail.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit Cc: freebsd-net@freebsd.org Subject: Re: ICMP attacks against TCP and PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 19:35:22 -0000 This helped me: /boot/loader.conf net.inet.tcp.hostcache.hashsize=65536 net.inet.tcp.hostcache.cachelimit=1966080 Actually, this is a workaround. As I remember, real problem is in tcp_ctlinput(), it could not update MTU for destination IP if hostcache allocation fails. tcp_hc_updatemtu() should returns NULL if tcp_hc_insert() returns NULL and tcp_ctlinput() should check this case and sets updated MTU for this particular connection if tcp_hc_updatemtu() fails. Otherwise we've got infinite loop in MTU discovery. On 15.01.2012 22:59, Nikolay Denev wrote: > > % uptime > 7:57PM up 608 days, 4:06, 1 user, load averages: 0.30, 0.21, 0.17 > > % vmstat -z|grep hostcache > hostcache: 136, 15372, 15136, 236, 44946965, 10972760 > > > Hmm… probably I should increase this…. > -- Andrey Zonov From owner-freebsd-net@FreeBSD.ORG Sun Jan 15 19:52:52 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 869A71065686 for ; Sun, 15 Jan 2012 19:52:52 +0000 (UTC) (envelope-from ndenev@gmail.com) Received: from mail-qw0-f47.google.com (mail-qw0-f47.google.com [209.85.216.47]) by mx1.freebsd.org (Postfix) with ESMTP id 4003A8FC1A for ; Sun, 15 Jan 2012 19:52:51 +0000 (UTC) Received: by qap15 with SMTP id 15so1990790qap.13 for ; Sun, 15 Jan 2012 11:52:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=references:in-reply-to:mime-version:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=qW7BJ3Ue0SJUXde5LUJYeanWLqqVlGB8yDjwxSg2ecU=; b=NBNH/Fu33R42V1FDhjqO+IhG4ClETNVqK8s7FpnqIGGPRN5x0QFHBia/YU1XWqp7/F tK7j+eHmk1iHNdJ7YXoOIfcHmnjf6isYXlUtH/QGNRNYrmFqhd7CtZtITbTxSPHlPeHO BIxPcTrOg5BJwZ7cglzrNFWHmduNDqQbC+Ycw= Received: by 10.224.181.10 with SMTP id bw10mr11041648qab.59.1326657171530; Sun, 15 Jan 2012 11:52:51 -0800 (PST) References: <4F131A7D.4020006@zonov.org> <733BE6AF-33E0-4C16-A222-B5F5D0519194@gmail.com> <12379405.15603.1326656127893.JavaMail.mobile-sync@vbzh28> In-Reply-To: <12379405.15603.1326656127893.JavaMail.mobile-sync@vbzh28> Mime-Version: 1.0 (1.0) From: Nikolay Denev Date: Sun, 15 Jan 2012 21:52:51 +0200 Message-ID: <3008402354236887854@unknownmsgid> To: Andrey Zonov Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Cc: "freebsd-net@freebsd.org" Subject: Re: ICMP attacks against TCP and PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Jan 2012 19:52:52 -0000 On 15.01.2012, at 21:35, Andrey Zonov wrote: > This helped me: > /boot/loader.conf > net.inet.tcp.hostcache.hashsizee536 > net.inet.tcp.hostcache.cachelimit=1966080 > > Actually, this is a workaround. As I remember, real problem is in > tcp_ctlinput(), it could not update MTU for destination IP if hostcache > allocation fails. tcp_hc_updatemtu() should returns NULL if > tcp_hc_insert() returns NULL and tcp_ctlinput() should check this case > and sets updated MTU for this particular connection if > tcp_hc_updatemtu() fails. Otherwise we've got infinite loop in MTU > discovery. > > > On 15.01.2012 22:59, Nikolay Denev wrote: >> >> % uptime >> 7:57PM up 608 days, 4:06, 1 user, load averages: 0.30, 0.21, 0.17 >> >> % vmstat -z|grep hostcache >> hostcache: 136, 15372, 15136, 236, 44946965, 1= 0972760 >> >> >> Hmm=85 probably I should increase this=85. >> > > -- > Andrey Zonov Thanks, I will test this asap! Regards, Nikolay From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 01:35:09 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DE5A01065670; Mon, 16 Jan 2012 01:35:09 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id B07B08FC0A; Mon, 16 Jan 2012 01:35:09 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0G1Z9QT000630; Mon, 16 Jan 2012 01:35:09 GMT (envelope-from linimon@freefall.freebsd.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0G1Z9s7000626; Mon, 16 Jan 2012 01:35:09 GMT (envelope-from linimon) Date: Mon, 16 Jan 2012 01:35:09 GMT Message-Id: <201201160135.q0G1Z9s7000626@freefall.freebsd.org> To: linimon@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-net@FreeBSD.org From: linimon@FreeBSD.org Cc: Subject: Re: kern/163370: [bpf] [request] enable zero-copy BPF by default X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 01:35:10 -0000 Old Synopsis: zero-copy BPF is disabled by default New Synopsis: [bpf] [request] enable zero-copy BPF by default Responsible-Changed-From-To: freebsd-bugs->freebsd-net Responsible-Changed-By: linimon Responsible-Changed-When: Mon Jan 16 01:32:37 UTC 2012 Responsible-Changed-Why: reclassify. http://www.freebsd.org/cgi/query-pr.cgi?pr=163370 From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 03:37:57 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8C841106566C; Mon, 16 Jan 2012 03:37:57 +0000 (UTC) (envelope-from julian@freebsd.org) Received: from vps1.elischer.org (vps1.elischer.org [204.109.63.16]) by mx1.freebsd.org (Postfix) with ESMTP id 637658FC08; Mon, 16 Jan 2012 03:37:57 +0000 (UTC) Received: from julian-mac.elischer.org (c-67-180-24-15.hsd1.ca.comcast.net [67.180.24.15]) (authenticated bits=0) by vps1.elischer.org (8.14.4/8.14.4) with ESMTP id q0G3bnui082229 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Sun, 15 Jan 2012 19:37:49 -0800 (PST) (envelope-from julian@freebsd.org) Message-ID: <4F139BC9.6030805@freebsd.org> Date: Sun, 15 Jan 2012 19:38:49 -0800 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9.2.25) Gecko/20111213 Thunderbird/3.1.17 MIME-Version: 1.0 To: Kostik Belousov References: <201201121404.q0CE4ItN066102@lurza.secnetix.de> <4F0FD2E3.1060607@freebsd.org> <20120113122749.GG31224@deviant.kiev.zoral.com.ua> In-Reply-To: <20120113122749.GG31224@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-hackers@freebsd.org, "Paul A. Procacci" , Oliver Fromme , Oliver Fromme , freebsd-net@freebsd.org Subject: Re: Processes' FIBs X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 03:37:57 -0000 On 1/13/12 4:27 AM, Kostik Belousov wrote: > On Thu, Jan 12, 2012 at 10:44:51PM -0800, Julian Elischer wrote: >> On 1/12/12 6:04 AM, Oliver Fromme wrote: >>> Bjoern A. Zeeb wrote: >>> > On 11. Jan 2012, at 15:06 , Oliver Fromme wrote: >>> > > I'm currently looking at the source code of ps, but adding >>> > > a field for the FIB isn't as trivial as I thought because >>> > > ps only sees struct kinfo_proc (via sysctl kern.proc.*) >>> > > which doesn't contain the FIB. procstat does the same. >>> > > >>> > > I'm currently trying to write a patch that copies p_fibnum >>> > > from struct proc to struct kinfo_proc (just like p_nice, >>> > > for example). Does that make sense? If so, does the patch >>> > > below look reasonable? (I've made it on a stable/8 system, >>> > > but it should apply to 9 and 10, too.) >>> > >>> > I am not sure it makes too much sense in ps. It might make sense in >>> > sockstat maybe? >>> >>> Well, every process has a default FIB number (p_fibnum in >>> struct proc). It is a property of the process, just like >>> the nice value for example. So I think it makes sense for >>> ps to be able to display it if the user asks for it. This >>> is the piece of information that I need. >>> >>> On the other hand, sockstat displays open sockets only. >>> Of course, an internet socket has a FIB number associated >>> with it, too, so sockstat could display it. But that >>> would be a completely different piece of information, >>> and it wouldn't solve the actual problem that I'm currently >>> facing. >>> >> I hadn't considered that a process would want to see the fib of another. >> but of course it makes sense. >> I see no problem the the attached patch except that it doesn't fix the >> man page for ps and setfib(2) or setfib(8) (or is it 1?) >> >> etc. >> if there are no objections, I can add this when it has been polished.. > The patch misses compat32 bits and breaks compat32 ps/top. I guess that would be "polishing" :-) >>> Best regards >>> Oliver >>> >>> --- ./sys/sys/user.h.orig 2011-07-12 14:23:54.000000000 +0200 >>> +++ ./sys/sys/user.h 2012-01-11 15:35:50.000000000 +0100 >>> @@ -83,7 +83,7 @@ >>> * it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and >>> * function kvm_proclist in lib/libkvm/kvm_proc.c . >>> */ >>> -#define KI_NSPARE_INT 9 >>> +#define KI_NSPARE_INT 8 >>> #define KI_NSPARE_LONG 12 >>> #define KI_NSPARE_PTR 6 >>> >>> @@ -177,6 +177,7 @@ >>> */ >>> char ki_sparestrings[68]; /* spare string space */ >>> int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ >>> + int ki_fibnum; /* Default FIB number */ >>> u_int ki_cr_flags; /* Credential flags */ >>> int ki_jid; /* Process jail ID */ >>> int ki_numthreads; /* XXXKSE number of threads in total >>> */ >>> --- ./sys/kern/kern_proc.c.orig 2011-07-12 14:19:26.000000000 +0200 >>> +++ ./sys/kern/kern_proc.c 2012-01-11 15:36:22.000000000 +0100 >>> @@ -775,6 +775,7 @@ >>> kp->ki_swtime = (ticks - p->p_swtick) / hz; >>> kp->ki_pid = p->p_pid; >>> kp->ki_nice = p->p_nice; >>> + kp->ki_fibnum = p->p_fibnum; >>> PROC_SLOCK(p); >>> rufetch(p,&kp->ki_rusage); >>> kp->ki_runtime = cputick2usec(p->p_rux.rux_runtime); >>> --- ./bin/ps/keyword.c.orig 2011-07-12 13:42:48.000000000 +0200 >>> +++ ./bin/ps/keyword.c 2012-01-11 15:44:27.000000000 +0100 >>> @@ -90,6 +90,7 @@ >>> NULL, 0}, >>> {"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, >>> 0}, >>> {"f", "F", NULL, 0, kvar, NULL, 8, KOFF(ki_flag), INT, "x", 0}, >>> + {"fib", "FIB", NULL, 0, kvar, NULL, 2, KOFF(ki_fibnum), INT, "d", 0}, >>> {"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, >>> {"ignored", "", "sigignore", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, >>> {"inblk", "INBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, >>> _______________________________________________ >>> freebsd-hackers@freebsd.org mailing list >>> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers >>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" >>> >> _______________________________________________ >> freebsd-net@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-net >> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 11:07:08 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 113B4106566B for ; Mon, 16 Jan 2012 11:07:08 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id F258C8FC0C for ; Mon, 16 Jan 2012 11:07:07 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0GB77fm057711 for ; Mon, 16 Jan 2012 11:07:07 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0GB77tU057709 for freebsd-net@FreeBSD.org; Mon, 16 Jan 2012 11:07:07 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 16 Jan 2012 11:07:07 GMT Message-Id: <201201161107.q0GB77tU057709@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-net@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-net@FreeBSD.org X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 11:07:08 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/163903 net [igb] "igb0:tx(0)","bpf interface lock" v2.2.5 9-STABL o kern/163482 net IP address is not round robined if DNS name has many o kern/163481 net freebsd do not add itself to ping route packet o kern/163370 net [bpf] [request] enable zero-copy BPF by default o kern/162927 net [tun] Modem-PPP error ppp[1538]: tun0: Phase: Clearing o kern/162926 net [ipfilter] Infinite loop in ipfilter with fragmented I o kern/162558 net [dummynet] [panic] seldom dummynet panics o kern/162509 net [re] [panic] Kernel panic may be related to if_re.c (r o kern/162352 net [patch] Enhancement: add SO_PROTO to socket.h o kern/162153 net [em] intel em driver 7.2.4 don't compile o kern/162110 net [igb] [panic] RELENG_9 panics on boot in IGB driver - o kern/162028 net [ixgbe] [patch] misplaced #endif in ixgbe.c o kern/161899 net [route] ntpd(8): Repeating RTM_MISS packets causing hi o kern/161381 net [re] RTL8169SC - re0: PHY write failed o kern/161277 net [em] [patch] BMC cannot receive IPMI traffic after loa o kern/160873 net [igb] igb(4) from HEAD fails to build on 7-STABLE o kern/160750 net Intel PRO/1000 connection breaks under load until rebo o kern/160693 net [gif] [em] Multicast packet are not passed from GIF0 t o kern/160420 net [msk] phy write timeout on HP 5310m o kern/160293 net [ieee80211] ppanic] kernel panic during network setup o kern/160206 net [gif] gifX stops working after a while (IPv6 tunnel) o kern/159817 net [udp] write UDPv4: No buffer space available (code=55) o kern/159795 net [tcp] excessive duplicate ACKs and TCP session freezes o kern/159629 net [ipsec] [panic] kernel panic with IPsec in transport m o kern/159621 net [tcp] [panic] panic: soabort: so_count o kern/159603 net [netinet] [patch] in_ifscrubprefix() - network route c o kern/159601 net [netinet] [patch] in_scrubprefix() - loopback route re o kern/159294 net [em] em watchdog timeouts o kern/159203 net [wpi] Intel 3945ABG Wireless LAN not support IBSS o kern/158930 net [bpf] BPF element leak in ifp->bpf_if->bif_dlist o kern/158726 net [ip6] [patch] ICMPv6 Router Announcement flooding limi o kern/158694 net [ix] [lagg] ix0 is not working within lagg(4) o kern/158665 net [ip6] [panic] kernel pagefault in in6_setscope() o kern/158635 net [em] TSO breaks BPF packet captures with em driver f kern/157802 net [dummynet] [panic] kernel panic in dummynet o kern/157785 net amd64 + jail + ipfw + natd = very slow outbound traffi o kern/157429 net [re] Realtek RTL8169 doesn't work with re(4) o kern/157418 net [em] em driver lockup during boot on Supermicro X9SCM- o kern/157410 net [ip6] IPv6 Router Advertisements Cause Excessive CPU U o kern/157287 net [re] [panic] INVARIANTS panic (Memory modified after f o kern/157209 net [ip6] [patch] locking error in rip6_input() (sys/netin o kern/157200 net [network.subr] [patch] stf(4) can not communicate betw o kern/157182 net [lagg] lagg interface not working together with epair o kern/156877 net [dummynet] [panic] dummynet move_pkt() null ptr derefe o kern/156667 net [em] em0 fails to init on CURRENT after March 17 o kern/156408 net [vlan] Routing failure when using VLANs vs. Physical e o kern/156328 net [icmp]: host can ping other subnet but no have IP from o kern/156317 net [ip6] Wrong order of IPv6 NS DAD/MLD Report o kern/156283 net [ip6] [patch] nd6_ns_input - rtalloc_mpath does not re o kern/156279 net [if_bridge][divert][ipfw] unable to correctly re-injec o kern/156226 net [lagg]: failover does not announce the failover to swi o kern/156030 net [ip6] [panic] Crash in nd6_dad_start() due to null ptr o kern/155772 net ifconfig(8): ioctl (SIOCAIFADDR): File exists on direc o kern/155680 net [multicast] problems with multicast s kern/155642 net [request] Add driver for Realtek RTL8191SE/RTL8192SE W o kern/155604 net [flowtable] Flowtable excessively caches dest MAC addr o kern/155597 net [panic] Kernel panics with "sbdrop" message o kern/155420 net [vlan] adding vlan break existent vlan o kern/155177 net [route] [panic] Panic when inject routes in kernel o kern/155030 net [igb] igb(4) DEVICE_POLLING does not work with carp(4) o kern/155010 net [msk] ntfs-3g via iscsi using msk driver cause kernel o kern/154943 net [gif] ifconfig gifX create on existing gifX clears IP s kern/154851 net [request]: Port brcm80211 driver from Linux to FreeBSD o kern/154850 net [netgraph] [patch] ng_ether fails to name nodes when t o kern/154679 net [em] Fatal trap 12: "em1 taskq" only at startup (8.1-R o kern/154600 net [tcp] [panic] Random kernel panics on tcp_output o kern/154557 net [tcp] Freeze tcp-session of the clients, if in the gat o kern/154443 net [if_bridge] Kernel module bridgestp.ko missing after u o kern/154286 net [netgraph] [panic] 8.2-PRERELEASE panic in netgraph o kern/154255 net [nfs] NFS not responding o kern/154214 net [stf] [panic] Panic when creating stf interface o kern/154185 net race condition in mb_dupcl o kern/154169 net [multicast] [ip6] Node Information Query multicast add o kern/154134 net [ip6] stuck kernel state in LISTEN on ipv6 daemon whic o kern/154091 net [netgraph] [panic] netgraph, unaligned mbuf? o conf/154062 net [vlan] [patch] change to way of auto-generatation of v o kern/153937 net [ral] ralink panics the system (amd64 freeBSDD 8.X) wh o kern/153936 net [ixgbe] [patch] MPRC workaround incorrectly applied to o kern/153816 net [ixgbe] ixgbe doesn't work properly with the Intel 10g o kern/153772 net [ixgbe] [patch] sysctls reference wrong XON/XOFF varia o kern/153497 net [netgraph] netgraph panic due to race conditions o kern/153454 net [patch] [wlan] [urtw] Support ad-hoc and hostap modes o kern/153308 net [em] em interface use 100% cpu o kern/153244 net [em] em(4) fails to send UDP to port 0xffff o kern/152893 net [netgraph] [panic] 8.2-PRERELEASE panic in netgraph o kern/152853 net [em] tftpd (and likely other udp traffic) fails over e o kern/152828 net [em] poor performance on 8.1, 8.2-PRE o kern/152569 net [net]: Multiple ppp connections and routing table prob o kern/152235 net [arp] Permanent local ARP entries are not properly upd o kern/152141 net [vlan] [patch] encapsulate vlan in ng_ether before out o kern/152036 net [libc] getifaddrs(3) returns truncated sockaddrs for n o kern/151690 net [ep] network connectivity won't work until dhclient is o kern/151681 net [nfs] NFS mount via IPv6 leads to hang on client with o kern/151593 net [igb] [panic] Kernel panic when bringing up igb networ o kern/150920 net [ixgbe][igb] Panic when packets are dropped with heade o kern/150557 net [igb] igb0: Watchdog timeout -- resetting o kern/150251 net [patch] [ixgbe] Late cable insertion broken o kern/150249 net [ixgbe] Media type detection broken o bin/150224 net ppp(8) does not reassign static IP after kill -KILL co f kern/149969 net [wlan] [ral] ralink rt2661 fails to maintain connectio o kern/149937 net [ipfilter] [patch] kernel panic in ipfilter IP fragmen o kern/149643 net [rum] device not sending proper beacon frames in ap mo o kern/149609 net [panic] reboot after adding second default route o kern/149117 net [inet] [patch] in_pcbbind: redundant test o kern/149086 net [multicast] Generic multicast join failure in 8.1 o kern/148018 net [flowtable] flowtable crashes on ia64 o kern/147912 net [boot] FreeBSD 8 Beta won't boot on Thinkpad i1300 11 o kern/147894 net [ipsec] IPv6-in-IPv4 does not work inside an ESP-only o kern/147155 net [ip6] setfb not work with ipv6 o kern/146845 net [libc] close(2) returns error 54 (connection reset by f kern/146792 net [flowtable] flowcleaner 100% cpu's core load o kern/146719 net [pf] [panic] PF or dumynet kernel panic o kern/146534 net [icmp6] wrong source address in echo reply o kern/146427 net [mwl] Additional virtual access points don't work on m o kern/146426 net [mwl] 802.11n rates not possible on mwl o kern/146425 net [mwl] mwl dropping all packets during and after high u f kern/146394 net [vlan] IP source address for outgoing connections o bin/146377 net [ppp] [tun] Interface doesn't clear addresses when PPP o kern/146358 net [vlan] wrong destination MAC address o kern/146165 net [wlan] [panic] Setting bssid in adhoc mode causes pani o kern/146082 net [ng_l2tp] a false invaliant check was performed in ng_ o kern/146037 net [panic] mpd + CoA = kernel panic o bin/145934 net [patch] add count option to netstat(1) o kern/145825 net [panic] panic: soabort: so_count o kern/145728 net [lagg] Stops working lagg between two servers. p kern/145600 net TCP/ECN behaves different to CE/CWR than ns2 reference f kern/144917 net [flowtable] [panic] flowtable crashes system [regressi o kern/144882 net MacBookPro =>4.1 does not connect to BSD in hostap wit o kern/144874 net [if_bridge] [patch] if_bridge frees mbuf after pfil ho o conf/144700 net [rc.d] async dhclient breaks stuff for too many people o kern/144616 net [nat] [panic] ip_nat panic FreeBSD 7.2 f kern/144315 net [ipfw] [panic] freebsd 8-stable reboot after add ipfw o kern/144231 net bind/connect/sendto too strict about sockaddr length o kern/143846 net [gif] bringing gif3 tunnel down causes gif0 tunnel to s kern/143673 net [stf] [request] there should be a way to support multi s kern/143666 net [ip6] [request] PMTU black hole detection not implemen o kern/143622 net [pfil] [patch] unlock pfil lock while calling firewall o kern/143593 net [ipsec] When using IPSec, tcpdump doesn't show outgoin o kern/143591 net [ral] RT2561C-based DLink card (DWL-510) fails to work o kern/143208 net [ipsec] [gif] IPSec over gif interface not working o kern/143034 net [panic] system reboots itself in tcp code [regression] o kern/142877 net [hang] network-related repeatable 8.0-STABLE hard hang o kern/142774 net Problem with outgoing connections on interface with mu o kern/142772 net [libc] lla_lookup: new lle malloc failed o kern/142018 net [iwi] [patch] Possibly wrong interpretation of beacon- o kern/141861 net [wi] data garbled with WEP and wi(4) with Prism 2.5 f kern/141741 net Etherlink III NIC won't work after upgrade to FBSD 8, o kern/140742 net rum(4) Two asus-WL167G adapters cannot talk to each ot o kern/140682 net [netgraph] [panic] random panic in netgraph o kern/140634 net [vlan] destroying if_lagg interface with if_vlan membe o kern/140619 net [ifnet] [patch] refine obsolete if_var.h comments desc o kern/140346 net [wlan] High bandwidth use causes loss of wlan connecti o kern/140142 net [ip6] [panic] FreeBSD 7.2-amd64 panic w/IPv6 o kern/140066 net [bwi] install report for 8.0 RC 2 (multiple problems) o kern/139565 net [ipfilter] ipfilter ioctl SIOCDELST broken o kern/139387 net [ipsec] Wrong lenth of PF_KEY messages in promiscuous o bin/139346 net [patch] arp(8) add option to remove static entries lis o kern/139268 net [if_bridge] [patch] allow if_bridge to forward just VL p kern/139204 net [arp] DHCP server replies rejected, ARP entry lost bef o kern/139117 net [lagg] + wlan boot timing (EBUSY) o kern/139058 net [ipfilter] mbuf cluster leak on FreeBSD 7.2 o kern/138850 net [dummynet] dummynet doesn't work correctly on a bridge o kern/138782 net [panic] sbflush_internal: cc 0 || mb 0xffffff004127b00 o kern/138688 net [rum] possibly broken on 8 Beta 4 amd64: able to wpa a o kern/138678 net [lo] FreeBSD does not assign linklocal address to loop o kern/138620 net [lagg] [patch] lagg port bpf-writes blocked o kern/138407 net [gre] gre(4) interface does not come up after reboot o kern/138332 net [tun] [lor] ifconfig tun0 destroy causes LOR if_adata/ o kern/138266 net [panic] kernel panic when udp benchmark test used as r o kern/138177 net [ipfilter] FreeBSD crashing repeatedly in ip_nat.c:257 f kern/138029 net [bpf] [panic] periodically kernel panic and reboot o kern/137881 net [netgraph] [panic] ng_pppoe fatal trap 12 p bin/137841 net [patch] wpa_supplicant(8) cannot verify SHA256 signed p kern/137776 net [rum] panic in rum(4) driver on 8.0-BETA2 o bin/137641 net ifconfig(8): various problems with "vlan_device.vlan_i o kern/137392 net [ip] [panic] crash in ip_nat.c line 2577 o kern/137372 net [ral] FreeBSD doesn't support wireless interface from o kern/137089 net [lagg] lagg falsely triggers IPv6 duplicate address de o bin/136994 net [patch] ifconfig(8) print carp mac address o kern/136911 net [netgraph] [panic] system panic on kldload ng_bpf.ko t o kern/136618 net [pf][stf] panic on cloning interface without unit numb o kern/135502 net [periodic] Warning message raised by rtfree function i o kern/134583 net [hang] Machine with jail freezes after random amount o o kern/134531 net [route] [panic] kernel crash related to routes/zebra o kern/134157 net [dummynet] dummynet loads cpu for 100% and make a syst o kern/133969 net [dummynet] [panic] Fatal trap 12: page fault while in o kern/133968 net [dummynet] [panic] dummynet kernel panic o kern/133736 net [udp] ip_id not protected ... o kern/133595 net [panic] Kernel Panic at pcpu.h:195 o kern/133572 net [ppp] [hang] incoming PPTP connection hangs the system o kern/133490 net [bpf] [panic] 'kmem_map too small' panic on Dell r900 o kern/133235 net [netinet] [patch] Process SIOCDLIFADDR command incorre f kern/133213 net arp and sshd errors on 7.1-PRERELEASE o kern/133060 net [ipsec] [pfsync] [panic] Kernel panic with ipsec + pfs o kern/132889 net [ndis] [panic] NDIS kernel crash on load BCM4321 AGN d o conf/132851 net [patch] rc.conf(5): allow to setfib(1) for service run o kern/132734 net [ifmib] [panic] panic in net/if_mib.c o kern/132705 net [libwrap] [patch] libwrap - infinite loop if hosts.all o kern/132672 net [ndis] [panic] ndis with rt2860.sys causes kernel pani o kern/132554 net [ipl] There is no ippool start script/ipfilter magic t o kern/132354 net [nat] Getting some packages to ipnat(8) causes crash o kern/132277 net [crypto] [ipsec] poor performance using cryptodevice f o kern/131781 net [ndis] ndis keeps dropping the link o kern/131776 net [wi] driver fails to init o kern/131753 net [altq] [panic] kernel panic in hfsc_dequeue o kern/131601 net [ipfilter] [panic] 7-STABLE panic in nat_finalise (tcp o bin/131567 net [socket] [patch] Update for regression/sockets/unix_cm o bin/131365 net route(8): route add changes interpretation of network f kern/130820 net [ndis] wpa_supplicant(8) returns 'no space on device' o kern/130628 net [nfs] NFS / rpc.lockd deadlock on 7.1-R o conf/130555 net [rc.d] [patch] No good way to set ipfilter variables a o kern/130525 net [ndis] [panic] 64 bit ar5008 ndisgen-erated driver cau o kern/130311 net [wlan_xauth] [panic] hostapd restart causing kernel pa o kern/130109 net [ipfw] Can not set fib for packets originated from loc f kern/130059 net [panic] Leaking 50k mbufs/hour f kern/129719 net [nfs] [panic] Panic during shutdown, tcp_ctloutput: in o kern/129517 net [ipsec] [panic] double fault / stack overflow f kern/129508 net [carp] [panic] Kernel panic with EtherIP (may be relat o kern/129219 net [ppp] Kernel panic when using kernel mode ppp o kern/129197 net [panic] 7.0 IP stack related panic o bin/128954 net ifconfig(8) deletes valid routes o bin/128602 net [an] wpa_supplicant(8) crashes with an(4) o kern/128448 net [nfs] 6.4-RC1 Boot Fails if NFS Hostname cannot be res o bin/128295 net [patch] ifconfig(8) does not print TOE4 or TOE6 capabi o bin/128001 net wpa_supplicant(8), wlan(4), and wi(4) issues o kern/127826 net [iwi] iwi0 driver has reduced performance and connecti o kern/127815 net [gif] [patch] if_gif does not set vlan attributes from o kern/127724 net [rtalloc] rtfree: 0xc5a8f870 has 1 refs f bin/127719 net [arp] arp: Segmentation fault (core dumped) f kern/127528 net [icmp]: icmp socket receives icmp replies not owned by p kern/127360 net [socket] TOE socket options missing from sosetopt() o bin/127192 net routed(8) removes the secondary alias IP of interface f kern/127145 net [wi]: prism (wi) driver crash at bigger traffic o kern/126895 net [patch] [ral] Add antenna selection (marked as TBD) o kern/126874 net [vlan]: Zebra problem if ifconfig vlanX destroy o kern/126695 net rtfree messages and network disruption upon use of if_ o kern/126339 net [ipw] ipw driver drops the connection o kern/126075 net [inet] [patch] internet control accesses beyond end of o bin/125922 net [patch] Deadlock in arp(8) o kern/125920 net [arp] Kernel Routing Table loses Ethernet Link status o kern/125845 net [netinet] [patch] tcp_lro_rx() should make use of hard o kern/125258 net [socket] socket's SO_REUSEADDR option does not work o kern/125239 net [gre] kernel crash when using gre o kern/124341 net [ral] promiscuous mode for wireless device ral0 looses o kern/124225 net [ndis] [patch] ndis network driver sometimes loses net o kern/124160 net [libc] connect(2) function loops indefinitely o kern/124021 net [ip6] [panic] page fault in nd6_output() o kern/123968 net [rum] [panic] rum driver causes kernel panic with WPA. o kern/123892 net [tap] [patch] No buffer space available o kern/123890 net [ppp] [panic] crash & reboot on work with PPP low-spee o kern/123858 net [stf] [patch] stf not usable behind a NAT o kern/123796 net [ipf] FreeBSD 6.1+VPN+ipnat+ipf: port mapping does not o kern/123758 net [panic] panic while restarting net/freenet6 o bin/123633 net ifconfig(8) doesn't set inet and ether address in one o kern/123559 net [iwi] iwi periodically disassociates/associates [regre o bin/123465 net [ip6] route(8): route add -inet6 -interfac o kern/123463 net [ipsec] [panic] repeatable crash related to ipsec-tool o conf/123330 net [nsswitch.conf] Enabling samba wins in nsswitch.conf c o kern/123160 net [ip] Panic and reboot at sysctl kern.polling.enable=0 o kern/122989 net [swi] [panic] 6.3 kernel panic in swi1: net o kern/122954 net [lagg] IPv6 EUI64 incorrectly chosen for lagg devices f kern/122780 net [lagg] tcpdump on lagg interface during high pps wedge o kern/122685 net It is not visible passing packets in tcpdump(1) o kern/122319 net [wi] imposible to enable ad-hoc demo mode with Orinoco o kern/122290 net [netgraph] [panic] Netgraph related "kmem_map too smal o kern/122033 net [ral] [lor] Lock order reversal in ral0 at bootup ieee o bin/121895 net [patch] rtsol(8)/rtsold(8) doesn't handle managed netw s kern/121774 net [swi] [panic] 6.3 kernel panic in swi1: net o kern/121555 net [panic] Fatal trap 12: current process = 12 (swi1: net o kern/121443 net [gif] [lor] icmp6_input/nd6_lookup o kern/121437 net [vlan] Routing to layer-2 address does not work on VLA o bin/121359 net [patch] [security] ppp(8): fix local stack overflow in o kern/121257 net [tcp] TSO + natd -> slow outgoing tcp traffic o kern/121181 net [panic] Fatal trap 3: breakpoint instruction fault whi o kern/120966 net [rum] kernel panic with if_rum and WPA encryption o kern/120566 net [request]: ifconfig(8) make order of arguments more fr o kern/120304 net [netgraph] [patch] netgraph source assumes 32-bit time o kern/120266 net [udp] [panic] gnugk causes kernel panic when closing U o bin/120060 net routed(8) deletes link-level routes in the presence of o kern/119945 net [rum] [panic] rum device in hostap mode, cause kernel o kern/119791 net [nfs] UDP NFS mount of aliased IP addresses from a Sol o kern/119617 net [nfs] nfs error on wpa network when reseting/shutdown f kern/119516 net [ip6] [panic] _mtx_lock_sleep: recursed on non-recursi o kern/119432 net [arp] route add -host -iface causes arp e o kern/119225 net [wi] 7.0-RC1 no carrier with Prism 2.5 wifi card [regr o kern/118727 net [netgraph] [patch] [request] add new ng_pf module o kern/117423 net [vlan] Duplicate IP on different interfaces o bin/117339 net [patch] route(8): loading routing management commands o kern/117271 net [tap] OpenVPN TAP uses 99% CPU on releng_6 when if_tap o bin/116643 net [patch] [request] fstat(1): add INET/INET6 socket deta o kern/116185 net [iwi] if_iwi driver leads system to reboot o kern/115239 net [ipnat] panic with 'kmem_map too small' using ipnat o kern/115019 net [netgraph] ng_ether upper hook packet flow stops on ad o kern/115002 net [wi] if_wi timeout. failed allocation (busy bit). ifco o kern/114915 net [patch] [pcn] pcn (sys/pci/if_pcn.c) ethernet driver f o kern/113432 net [ucom] WARNING: attempt to net_add_domain(netgraph) af o kern/112722 net [ipsec] [udp] IP v4 udp fragmented packet reject o kern/112686 net [patm] patm driver freezes System (FreeBSD 6.2-p4) i38 o bin/112557 net [patch] ppp(8) lock file should not use symlink name o kern/112528 net [nfs] NFS over TCP under load hangs with "impossible p o kern/111537 net [inet6] [patch] ip6_input() treats mbuf cluster wrong o kern/111457 net [ral] ral(4) freeze o kern/110284 net [if_ethersubr] Invalid Assumption in SIOCSIFADDR in et o kern/110249 net [kernel] [regression] [patch] setsockopt() error regre o kern/109470 net [wi] Orinoco Classic Gold PC Card Can't Channel Hop o bin/108895 net pppd(8): PPPoE dead connections on 6.2 [regression] o kern/107944 net [wi] [patch] Forget to unlock mutex-locks o conf/107035 net [patch] bridge(8): bridge interface given in rc.conf n o kern/106444 net [netgraph] [panic] Kernel Panic on Binding to an ip to o kern/106438 net [ipf] ipfilter: keep state does not seem to allow repl o kern/106316 net [dummynet] dummynet with multipass ipfw drops packets o kern/105945 net Address can disappear from network interface s kern/105943 net Network stack may modify read-only mbuf chain copies o bin/105925 net problems with ifconfig(8) and vlan(4) [regression] o kern/104851 net [inet6] [patch] On link routes not configured when usi o kern/104751 net [netgraph] kernel panic, when getting info about my tr o kern/103191 net Unpredictable reboot o kern/103135 net [ipsec] ipsec with ipfw divert (not NAT) encodes a pac o kern/102540 net [netgraph] [patch] supporting vlan(4) by ng_fec(4) o conf/102502 net [netgraph] [patch] ifconfig name does't rename netgrap o kern/102035 net [plip] plip networking disables parallel port printing o kern/101948 net [ipf] [panic] Kernel Panic Trap No 12 Page Fault - cau o kern/100709 net [libc] getaddrinfo(3) should return TTL info o kern/100519 net [netisr] suggestion to fix suboptimal network polling o kern/98978 net [ipf] [patch] ipfilter drops OOW packets under 6.1-Rel o kern/98597 net [inet6] Bug in FreeBSD 6.1 IPv6 link-local DAD procedu o bin/98218 net wpa_supplicant(8) blacklist not working o kern/97306 net [netgraph] NG_L2TP locks after connection with failed o conf/97014 net [gif] gifconfig_gif? in rc.conf does not recognize IPv f kern/96268 net [socket] TCP socket performance drops by 3000% if pack o kern/95519 net [ral] ral0 could not map mbuf o kern/95288 net [pppd] [tty] [panic] if_ppp panic in sys/kern/tty_subr o kern/95277 net [netinet] [patch] IP Encapsulation mask_match() return o kern/95267 net packet drops periodically appear f kern/93378 net [tcp] Slow data transfer in Postfix and Cyrus IMAP (wo o kern/93019 net [ppp] ppp and tunX problems: no traffic after restarti o kern/92880 net [libc] [patch] almost rewritten inet_network(3) functi s kern/92279 net [dc] Core faults everytime I reboot, possible NIC issu o kern/91859 net [ndis] if_ndis does not work with Asus WL-138 s kern/91777 net [ipf] [patch] wrong behaviour with skip rule inside an o kern/91364 net [ral] [wep] WF-511 RT2500 Card PCI and WEP o kern/91311 net [aue] aue interface hanging s kern/90086 net [hang] 5.4p8 on supermicro P8SCT hangs during boot if o kern/87521 net [ipf] [panic] using ipfilter "auth" keyword leads to k o kern/87421 net [netgraph] [panic]: ng_ether + ng_eiface + if_bridge s kern/86920 net [ndis] ifconfig: SIOCS80211: Invalid argument [regress o kern/86871 net [tcp] [patch] allocation logic for PCBs in TIME_WAIT s o kern/86427 net [lor] Deadlock with FASTIPSEC and nat o kern/86103 net [ipf] Illegal NAT Traversal in IPFilter o kern/85780 net 'panic: bogus refcnt 0' in routing/ipv6 o bin/85445 net ifconfig(8): deprecated keyword to ifconfig inoperativ p kern/85320 net [gre] [patch] possible depletion of kernel stack in ip o bin/82975 net route change does not parse classfull network as given o kern/82881 net [netgraph] [panic] ng_fec(4) causes kernel panic after o kern/82468 net Using 64MB tcp send/recv buffers, trafficflow stops, i o bin/82185 net [patch] ndp(8) can delete the incorrect entry o kern/81095 net IPsec connection stops working if associated network i o kern/78968 net FreeBSD freezes on mbufs exhaustion (network interface o kern/78090 net [ipf] ipf filtering on bridged packets doesn't work if o kern/77341 net [ip6] problems with IPV6 implementation o kern/77273 net [ipf] ipfilter breaks ipv6 statefull filtering on 5.3 s kern/77195 net [ipf] [patch] ipfilter ioctl SIOCGNATL does not match o kern/75873 net Usability problem with non-RFC-compliant IP spoof prot s kern/75407 net [an] an(4): no carrier after short time a kern/71474 net [route] route lookup does not skip interfaces marked d o kern/71469 net default route to internet magically disappears with mu o kern/70904 net [ipf] ipfilter ipnat problem with h323 proxy support o kern/68889 net [panic] m_copym, length > size of mbuf chain o kern/66225 net [netgraph] [patch] extend ng_eiface(4) control message o kern/65616 net IPSEC can't detunnel GRE packets after real ESP encryp s kern/60293 net [patch] FreeBSD arp poison patch a kern/56233 net IPsec tunnel (ESP) over IPv6: MTU computation is wrong s bin/41647 net ifconfig(8) doesn't accept lladdr along with inet addr s kern/39937 net ipstealth issue a kern/38554 net [patch] changing interface ipaddress doesn't seem to w o kern/34665 net [ipf] [hang] ipfilter rcmd proxy "hangs". o kern/31940 net ip queue length too short for >500kpps o kern/31647 net [libc] socket calls can return undocumented EINVAL o kern/30186 net [libc] getaddrinfo(3) does not handle incorrect servna o kern/27474 net [ipf] [ppp] Interactive use of user PPP and ipfilter c f kern/24959 net [patch] proper TCP_NOPUSH/TCP_CORK compatibility o conf/23063 net [arp] [patch] for static ARP tables in rc.network o kern/21998 net [socket] [patch] ident only for outgoing connections o kern/5877 net [socket] sb_cc counts control data as well as data dat 384 problems total. From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 18:28:26 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 122071065670 for ; Mon, 16 Jan 2012 18:28:26 +0000 (UTC) (envelope-from nitroboost@gmail.com) Received: from mail-tul01m020-f182.google.com (mail-tul01m020-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id D08918FC14 for ; Mon, 16 Jan 2012 18:28:25 +0000 (UTC) Received: by obcwo16 with SMTP id wo16so1841284obc.13 for ; Mon, 16 Jan 2012 10:28:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=n2qiTEyrocucvSa3yUo1tM/0X1lw/xgpbbKCyweREho=; b=KkIz/6RBDaD6AO0oVDFFI3VTR0EVAlMiYUNtUYUkvKMeJOkRtEZqSMnGlzVpmnvBVF MUNoki1kC4AzzBLl6JoXWsjW8ZmEzdwjI6NSUe0h3owvKFOv8JVF3fbxdy1hBTy06NXj s4J7Qe4m1JK3v/V//ZXBwDHeV98FSbfTX0WDo= MIME-Version: 1.0 Received: by 10.182.74.97 with SMTP id s1mr11960922obv.42.1326737127241; Mon, 16 Jan 2012 10:05:27 -0800 (PST) Received: by 10.182.225.100 with HTTP; Mon, 16 Jan 2012 10:05:27 -0800 (PST) In-Reply-To: <4F13265C.1040200@zonov.org> References: <4F13265C.1040200@zonov.org> Date: Mon, 16 Jan 2012 11:05:27 -0700 Message-ID: From: Jason Wolfe To: Andrey Zonov Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: freebsd-net@freebsd.org Subject: Re: em loses link after IPMI reset X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 18:28:26 -0000 Andrey, Are you running Supermicro hardware by chance? We had a very similar issue that was caused by a buggy version of the IPMI firmware on a good number of machines with the same 82574 chips. At any rate, might give the IPMI update a try and see if that changes the behavior at all. Jason On Sun, Jan 15, 2012 at 12:17 PM, Andrey Zonov wrote: > Hi, > > I have a few boxes with Intel 82574L NIC that run under 8.2-STABLE. After > execution `ipmitool mc reset cold' NIC loses link and after negotiation it > sets 100TX media type (normal is 1000T). Under Linux on the same box this > problem doesn't occur, after BMC reset driver doesn't lose link. > > It seems that em driver sets (or doesn't set) some IPMI relied registers. > In Linux there is some magic about 82574/82583 chips and IPMI [1]. What > do you think this is a solution for my problem or this is about something > else? > > > [1] > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/net/ethernet/intel/e1000e/netdev.c;h=3911401ed65d59ceafe9b28080a6630f4adf6371;hb=HEAD#l2696 > > -- > Andrey Zonov > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" > From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 18:58:23 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D462F106566C for ; Mon, 16 Jan 2012 18:58:23 +0000 (UTC) (envelope-from andrey@zonov.org) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id 609B58FC0C for ; Mon, 16 Jan 2012 18:58:22 +0000 (UTC) Received: by bke17 with SMTP id 17so1108016bke.13 for ; Mon, 16 Jan 2012 10:58:22 -0800 (PST) Received: by 10.205.121.139 with SMTP id gc11mr4040131bkc.26.1326739860025; Mon, 16 Jan 2012 10:51:00 -0800 (PST) Received: from [10.254.254.77] (ppp95-165-131-163.pppoe.spdop.ru. [95.165.131.163]) by mx.google.com with ESMTPS id ig13sm9174380bkc.9.2012.01.16.10.50.59 (version=SSLv3 cipher=OTHER); Mon, 16 Jan 2012 10:50:59 -0800 (PST) Message-ID: <4F14718E.3020203@zonov.org> Date: Mon, 16 Jan 2012 22:50:54 +0400 From: Andrey Zonov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.24) Gecko/20100228 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: Jason Wolfe References: <4F13265C.1040200@zonov.org> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: em loses link after IPMI reset X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 18:58:23 -0000 Hi, No, these are ASUS machines (Z8NR-D12 with ASMB4-iKVM). My Supermicro machines have igb NICs, they don't lose link when BMC is resetting. On 16.01.2012 22:05, Jason Wolfe wrote: > Andrey, > > Are you running Supermicro hardware by chance? We had a very similar > issue that was caused by a buggy version of the IPMI firmware on a good > number of machines with the same 82574 chips. At any rate, might give > the IPMI update a try and see if that changes the behavior at all. > > Jason > > On Sun, Jan 15, 2012 at 12:17 PM, Andrey Zonov > wrote: > > Hi, > > I have a few boxes with Intel 82574L NIC that run under 8.2-STABLE. > After execution `ipmitool mc reset cold' NIC loses link and after > negotiation it sets 100TX media type (normal is 1000T). Under Linux > on the same box this problem doesn't occur, after BMC reset driver > doesn't lose link. > > It seems that em driver sets (or doesn't set) some IPMI relied > registers. In Linux there is some magic about 82574/82583 chips and > IPMI [1]. What do you think this is a solution for my problem or > this is about something else? > > > [1] > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/net/ethernet/intel/e1000e/netdev.c;h=3911401ed65d59ceafe9b28080a6630f4adf6371;hb=HEAD#l2696 > > -- > Andrey Zonov > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to > "freebsd-net-unsubscribe@freebsd.org > " > > -- Andrey Zonov From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 19:30:25 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 164E41065670 for ; Mon, 16 Jan 2012 19:30:25 +0000 (UTC) (envelope-from kes-kes@yandex.ru) Received: from forward20.mail.yandex.net (forward20.mail.yandex.net [IPv6:2a02:6b8:0:1402::5]) by mx1.freebsd.org (Postfix) with ESMTP id 86EE28FC16 for ; Mon, 16 Jan 2012 19:30:24 +0000 (UTC) Received: from smtp18.mail.yandex.net (smtp18.mail.yandex.net [95.108.252.18]) by forward20.mail.yandex.net (Yandex) with ESMTP id 079401040DFD for ; Mon, 16 Jan 2012 23:30:23 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1326742223; bh=Ca/x7AaZg1ivjIBFlINVnNvL3PxfkIPvb5NjrHN8Lks=; h=Date:From:Reply-To:Message-ID:To:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding; b=JwygL0bK7C95ktQ5WNwae1MQK8ISh46p9V4XSsOlOhMKY1J7kHTxak1ssVix1qa3g G/Qh15ds1qOthPto/gr2RAF0Hov7mbrx3gCe9yKcKrcSyza3hUc2j9+VyU8VDIjKnK rOEAjM3lACcWH5GnzTYB3NnhFHx/6BL5Sm+WqZvk= Received: from smtp18.mail.yandex.net (localhost [127.0.0.1]) by smtp18.mail.yandex.net (Yandex) with ESMTP id E327A18A0143 for ; Mon, 16 Jan 2012 23:30:22 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1326742222; bh=Ca/x7AaZg1ivjIBFlINVnNvL3PxfkIPvb5NjrHN8Lks=; h=Date:From:Reply-To:Message-ID:To:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding; b=ZTY1qgwfmQCI9QDEXR1wrnjbHS6S3BD/07ebfILQ7YFLoFU6t1f7j8kWDN4LGcYwF wm3t/08x1tZ22boU1rNAYmr8LvNs0ulpNM7HoGP3KN+JJBa0BF18xyDrMsrWKAqAcm Qlmdjgnt+U2cegGwKU1Pu2lMxf1KnO8zgr7RGaAY= Received: from unknown (unknown [77.93.52.22]) by smtp18.mail.yandex.net (nwsmtp/Yandex) with ESMTP id UMKWS5kg-UMKmfZlu; Mon, 16 Jan 2012 23:30:22 +0400 X-Yandex-Spam: 1 Date: Mon, 16 Jan 2012 21:30:20 +0200 From: =?windows-1251?B?yu7t/Oru4iDF4uPl7ejp?= X-Mailer: The Bat! (v4.0.24) Professional Organization: =?windows-1251?B?188gyu7t/Oru4iwgRnJlZUxpbmU=?= X-Priority: 3 (Normal) Message-ID: <182490204.20120116213020@yandex.ru> To: freebsd-net@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=windows-1251 Content-Transfer-Encoding: 8bit Cc: Subject: documentation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: =?windows-1251?B?yu7t/Oru4iDF4uPl7ejp?= List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 19:30:25 -0000 Hi. Can any one describe packetflow in kernel structures and the algorithm how netisr is worked. and how packet are queued and scheduled to CPU I want to try to optimize its algorithm of working Thank you. From owner-freebsd-net@FreeBSD.ORG Mon Jan 16 19:46:56 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 43F5D1065676 for ; Mon, 16 Jan 2012 19:46:56 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mail.allbsd.org (gatekeeper-int.allbsd.org [IPv6:2001:2f0:104:e002::2]) by mx1.freebsd.org (Postfix) with ESMTP id B01E98FC0C for ; Mon, 16 Jan 2012 19:46:55 +0000 (UTC) Received: from alph.allbsd.org ([IPv6:2001:2f0:104:e010:862b:2bff:febc:8956]) (authenticated bits=128) by mail.allbsd.org (8.14.4/8.14.4) with ESMTP id q0GJkeZf084901; Tue, 17 Jan 2012 04:46:50 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.allbsd.org (8.14.4/8.14.4) with ESMTP id q0GJkblW086025; Tue, 17 Jan 2012 04:46:40 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Tue, 17 Jan 2012 04:45:33 +0900 (JST) Message-Id: <20120117.044533.1784742896398431105.hrs@allbsd.org> To: dk@neveragain.de From: Hiroki Sato In-Reply-To: <20120110102405.GA82356@neveragain.de> References: <20120110102405.GA82356@neveragain.de> X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.3.51 on Emacs 23.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart0(Tue_Jan_17_04_45_33_2012_849)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.97 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.3 (mail.allbsd.org [IPv6:2001:2f0:104:e001::32]); Tue, 17 Jan 2012 04:46:53 +0900 (JST) X-Spam-Status: No, score=-104.4 required=13.0 tests=BAYES_00, CONTENT_TYPE_PRESENT, QENCPTR2, RDNS_NONE, SPF_SOFTFAIL, USER_IN_WHITELIST autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on gatekeeper.allbsd.org Cc: freebsd-net@FreeBSD.org Subject: Re: Unnecessary sleep in network.subr: ipv6_up() X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Jan 2012 19:46:56 -0000 ----Security_Multipart0(Tue_Jan_17_04_45_33_2012_849)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Tue_Jan_17_04_45_33_2012_075)--" Content-Transfer-Encoding: 7bit ----Next_Part(Tue_Jan_17_04_45_33_2012_075)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Dennis Koegel wrote in <20120110102405.GA82356@neveragain.de>: dk> Cheers, dk> dk> problem: Having a *lot* of IPv6 interfaces (Vlan interfaces in this case) dk> causes a huge and annoying delay time at system boot in 9.0R. dk> dk> ipv6_up() in network.subr does this: dk> dk> + # wait for DAD dk> + sleep `${SYSCTL_N} net.inet6.ip6.dad_count` dk> + sleep 1 dk> dk> This happens for each and every interface, at a minimum (and default) of dk> two seconds per interface. dk> dk> It seems the behaviour was introduced with r197139. Before this merge, dk> /etc/rc.d/network_ipv6 did the same sleeps, but only once for the whole dk> network startup. dk> dk> I don't see why this should happen per interface, so I suggest the extra dk> sleeps are limited to "once per network startup" once again (or maybe dk> removed?). Can you try the attached patch and let me know if it works fine on your system? -- Hiroki ----Next_Part(Tue_Jan_17_04_45_33_2012_075)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="etc_dadwait.20120117-1.diff" Index: etc/network.subr =================================================================== --- etc/network.subr (revision 230227) +++ etc/network.subr (working copy) @@ -559,10 +559,6 @@ ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 ipv6_accept_rtadv_up ${_if} && _ret=0 - # wait for DAD - sleep `${SYSCTL_N} net.inet6.ip6.dad_count` - sleep 1 - return $_ret } Index: etc/rc.d/netif =================================================================== --- etc/rc.d/netif (revision 230227) +++ etc/rc.d/netif (working copy) @@ -123,16 +123,26 @@ _cooked_list="`list_net_interfaces`" fi + _dadwait= _fail= _ok= for ifn in ${_cooked_list}; do if ${_func} ${ifn} $2; then _ok="${_ok} ${ifn}" + if ipv6if ${ifn}; then + _dadwait=1 + fi else _fail="${_fail} ${ifn}" fi done + # inet6 address configuration needs sleep for DAD. + if [ -n "${_dadwait}" ]; then + sleep `${SYSCTL_N} net.inet6.ip6.dad_count` + sleep 1 + fi + _str= if [ -n "${_ok}" ]; then case ${_func} in ----Next_Part(Tue_Jan_17_04_45_33_2012_075)---- ----Security_Multipart0(Tue_Jan_17_04_45_33_2012_849)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iEYEABECAAYFAk8Ufl0ACgkQTyzT2CeTzy3sNQCfXds1WoPW+0VaVmVZZvGnOVtG PesAn0sjZ077ENZgwnbfKIhYrqjATcUC =yLXv -----END PGP SIGNATURE----- ----Security_Multipart0(Tue_Jan_17_04_45_33_2012_849)---- From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 12:21:45 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B1F4D106566B; Tue, 17 Jan 2012 12:21:45 +0000 (UTC) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (lurza.secnetix.de [IPv6:2a01:170:102f::2]) by mx1.freebsd.org (Postfix) with ESMTP id 273968FC0A; Tue, 17 Jan 2012 12:21:44 +0000 (UTC) Received: from lurza.secnetix.de (localhost [127.0.0.1]) by lurza.secnetix.de (8.14.3/8.14.3) with ESMTP id q0HCLSBG034507; Tue, 17 Jan 2012 13:21:43 +0100 (CET) (envelope-from oliver.fromme@secnetix.de) Received: (from olli@localhost) by lurza.secnetix.de (8.14.3/8.14.3/Submit) id q0HCLRsh034506; Tue, 17 Jan 2012 13:21:27 +0100 (CET) (envelope-from olli) Date: Tue, 17 Jan 2012 13:21:27 +0100 (CET) Message-Id: <201201171221.q0HCLRsh034506@lurza.secnetix.de> From: Oliver Fromme To: Kostik Belousov , freebsd-net@FreeBSD.ORG, Julian Elischer , freebsd-hackers@FreeBSD.ORG, Oliver Fromme In-Reply-To: X-Newsgroups: list.freebsd-net User-Agent: tin/1.9.6-20101126 ("Burnside") (UNIX) (FreeBSD/6.4-PRERELEASE-20080904 (i386)) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.3.9 (lurza.secnetix.de [127.0.0.1]); Tue, 17 Jan 2012 13:21:43 +0100 (CET) Cc: Subject: Re: Processes' FIBs X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 12:21:45 -0000 Kostik Belousov wrote: > The patch misses compat32 bits and breaks compat32 ps/top. Right, thank you for pointing it out! I missed it because I only have i386 for testing. I've created new patch sets for releng8 and current. These include compat32 support and an entry for the manual page. Would someone with amd64 please test the compat32 part? I've been using this code on i386 for a few days without any problems. I've attached the patch for current below. Both patch sets are also available from this URL: http://www.secnetix.de/olli/tmp/ki_fibnum/ Testing is easy: Apply the patch, rebuild bin/ps and kernel. Make sure that your kernel config has "options ROUTETABLES=16" so multiple FIBs are supported. Reboot. Open a shell with setfib, e.g. "setfib 3 /bin/sh" (no root required), type "ps -ax -o user,pid,fib,command" or something similar, and verify that the shell process and its children are listed with the correct FIB. When testing on amd64, use both the native ps and an i386 binary. Thank you very much! Best regards Oliver --- sys/sys/user.h.orig 2011-11-07 22:13:19.000000000 +0100 +++ sys/sys/user.h 2012-01-17 11:33:59.000000000 +0100 @@ -83,7 +83,7 @@ * it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and * function kvm_proclist in lib/libkvm/kvm_proc.c . */ -#define KI_NSPARE_INT 9 +#define KI_NSPARE_INT 8 #define KI_NSPARE_LONG 12 #define KI_NSPARE_PTR 6 @@ -186,6 +186,7 @@ */ char ki_sparestrings[50]; /* spare string space */ int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ + int ki_fibnum; /* Default FIB number */ u_int ki_cr_flags; /* Credential flags */ int ki_jid; /* Process jail ID */ int ki_numthreads; /* XXXKSE number of threads in total */ --- sys/kern/kern_proc.c.orig 2012-01-15 19:47:24.000000000 +0100 +++ sys/kern/kern_proc.c 2012-01-17 12:52:36.000000000 +0100 @@ -836,6 +836,7 @@ kp->ki_swtime = (ticks - p->p_swtick) / hz; kp->ki_pid = p->p_pid; kp->ki_nice = p->p_nice; + kp->ki_fibnum = p->p_fibnum; kp->ki_start = p->p_stats->p_start; timevaladd(&kp->ki_start, &boottime); PROC_SLOCK(p); @@ -1121,6 +1122,7 @@ bcopy(ki->ki_comm, ki32->ki_comm, COMMLEN + 1); bcopy(ki->ki_emul, ki32->ki_emul, KI_EMULNAMELEN + 1); bcopy(ki->ki_loginclass, ki32->ki_loginclass, LOGINCLASSLEN + 1); + CP(*ki, *ki32, ki_fibnum); CP(*ki, *ki32, ki_cr_flags); CP(*ki, *ki32, ki_jid); CP(*ki, *ki32, ki_numthreads); --- sys/compat/freebsd32/freebsd32.h.orig 2011-11-11 08:17:00.000000000 +0100 +++ sys/compat/freebsd32/freebsd32.h 2012-01-17 11:34:00.000000000 +0100 @@ -319,6 +319,7 @@ char ki_loginclass[LOGINCLASSLEN+1]; char ki_sparestrings[50]; int ki_spareints[KI_NSPARE_INT]; + int ki_fibnum; u_int ki_cr_flags; int ki_jid; int ki_numthreads; --- bin/ps/keyword.c.orig 2011-09-29 08:31:42.000000000 +0200 +++ bin/ps/keyword.c 2012-01-17 12:54:49.000000000 +0100 @@ -85,6 +85,7 @@ {"etimes", "ELAPSED", NULL, USER, elapseds, 0, CHAR, NULL, 0}, {"euid", "", "uid", 0, NULL, 0, CHAR, NULL, 0}, {"f", "F", NULL, 0, kvar, KOFF(ki_flag), INT, "x", 0}, + {"fib", "FIB", NULL, 0, kvar, NULL, 2, KOFF(ki_fibnum), INT, "d", 0}, {"flags", "", "f", 0, NULL, 0, CHAR, NULL, 0}, {"gid", "GID", NULL, 0, kvar, KOFF(ki_groups), UINT, UIDFMT, 0}, {"group", "GROUP", NULL, LJUST, egroupname, 0, CHAR, NULL, 0}, --- bin/ps/ps.1.orig 2011-11-22 22:53:06.000000000 +0100 +++ bin/ps/ps.1 2012-01-17 12:56:17.000000000 +0100 @@ -29,7 +29,7 @@ .\" @(#)ps.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD: src/bin/ps/ps.1,v 1.112 2011/11/22 21:53:06 trociny Exp $ .\" -.Dd November 22, 2011 +.Dd January 17, 2012 .Dt PS 1 .Os .Sh NAME @@ -506,6 +506,9 @@ minutes:seconds. .It Cm etimes elapsed running time, in decimal integer seconds +.It Cm fib +default FIB number, see +.Xr setfib 1 .It Cm flags the process flags, in hexadecimal (alias .Cm f ) From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 14:11:18 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 91251106564A; Tue, 17 Jan 2012 14:11:18 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 66FE68FC08; Tue, 17 Jan 2012 14:11:18 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0HEBIbH004051; Tue, 17 Jan 2012 14:11:18 GMT (envelope-from glebius@freefall.freebsd.org) Received: (from glebius@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0HEBIQQ004045; Tue, 17 Jan 2012 14:11:18 GMT (envelope-from glebius) Date: Tue, 17 Jan 2012 14:11:18 GMT Message-Id: <201201171411.q0HEBIQQ004045@freefall.freebsd.org> To: glebius@FreeBSD.org, freebsd-net@FreeBSD.org, kmacy@FreeBSD.org From: glebius@FreeBSD.org Cc: Subject: Re: kern/155604: [flowtable] Flowtable excessively caches dest MAC addresses for outgoing traffic X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 14:11:18 -0000 Synopsis: [flowtable] Flowtable excessively caches dest MAC addresses for outgoing traffic Responsible-Changed-From-To: freebsd-net->kmacy Responsible-Changed-By: glebius Responsible-Changed-When: Tue Jan 17 14:10:55 UTC 2012 Responsible-Changed-Why: Over to author of flowtable. http://www.freebsd.org/cgi/query-pr.cgi?pr=155604 From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 15:17:22 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3EC7F1065673 for ; Tue, 17 Jan 2012 15:17:22 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id 148E38FC12 for ; Tue, 17 Jan 2012 15:17:22 +0000 (UTC) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [96.47.65.170]) by cyrus.watson.org (Postfix) with ESMTPSA id B272F46B23; Tue, 17 Jan 2012 10:17:21 -0500 (EST) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 1183BB993; Tue, 17 Jan 2012 10:17:21 -0500 (EST) From: John Baldwin To: pyunyh@gmail.com Date: Tue, 17 Jan 2012 10:12:23 -0500 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p10; KDE/4.5.5; amd64; ; ) References: <1326560151.30035.YahooMailNeo@web36505.mail.mud.yahoo.com> <20120114225358.GA22889@michelle.cdnetworks.com> In-Reply-To: <20120114225358.GA22889@michelle.cdnetworks.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201201171012.23725.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Tue, 17 Jan 2012 10:17:21 -0500 (EST) Cc: "freebsd-net@freebsd.org" , Bill Norton Subject: Re: bge0 interface seen but not working X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 15:17:22 -0000 On Saturday, January 14, 2012 5:53:58 pm YongHyeon PYUN wrote: > On Sat, Jan 14, 2012 at 08:55:51AM -0800, Bill Norton wrote: > > Greetings, > > > > I posted this on the pc-bsd forum and was directed here.? > > > > I installed the latest 8.X and the interface worked fine.? > > > > Yesterday, I did a clean install of 9.0.? > > > > The issue is that the bge0 interface is not working.? > > It is seen by the kernel(ifconfig shows it) but just won't ping. > > I have tried dhcp and a static address.? > > I used a backtrack live cd and this worked fine.? > > > > Probably disabling MSI will workaround your issue. Add > > hw.pci.enable_msi="0" > > to /boot/loader.conf. > > > > > I did find this bug below but it seemed to only affect 8.2 > > > > The bge(4) Ethernet driver has a known issue where the interface is seen but does not respond to networking requests. A patch is available for 8.2 (see 155442) and the driver will be fixed in 8.3. > > > > Any ideas?? > > > > I thought it was already fixed by John but it seems it is not. > John, would you take a look?(NVIDIA HT MSI issue)? It is not fully resolved. 9 has some different changes, but those changes broke other systems. It seems MSI on NVIDIA HT systems requires a lot of extra quirks to actually work. -- John Baldwin From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 19:08:07 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9C9A21065676 for ; Tue, 17 Jan 2012 19:08:07 +0000 (UTC) (envelope-from guru@unixarea.de) Received: from ms16-1.1blu.de (ms16-1.1blu.de [89.202.0.34]) by mx1.freebsd.org (Postfix) with ESMTP id 5C3EC8FC1A for ; Tue, 17 Jan 2012 19:08:07 +0000 (UTC) Received: from [82.113.121.173] (helo=tiny.Sisis.de) by ms16-1.1blu.de with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1RnEO5-00045O-SE for freebsd-net@freebsd.org; Tue, 17 Jan 2012 20:08:06 +0100 Received: from tiny.Sisis.de (localhost [127.0.0.1]) by tiny.Sisis.de (8.14.5/8.14.3) with ESMTP id q0HJ8nf9001281 for ; Tue, 17 Jan 2012 20:08:51 +0100 (CET) (envelope-from guru@unixarea.de) Received: (from guru@localhost) by tiny.Sisis.de (8.14.5/8.14.3/Submit) id q0HJ8moG001280 for freebsd-net@freebsd.org; Tue, 17 Jan 2012 20:08:48 +0100 (CET) (envelope-from guru@unixarea.de) X-Authentication-Warning: tiny.Sisis.de: guru set sender to guru@unixarea.de using -f Date: Tue, 17 Jan 2012 20:08:48 +0100 From: Matthias Apitz To: freebsd-net@freebsd.org Message-ID: <20120117190847.GA1255@tiny> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Operating-System: FreeBSD 10.0-CURRENT r226986 (i386) User-Agent: Mutt/1.5.21 (2010-09-15) X-Con-Id: 51246 X-Originating-IP: 82.113.121.173 Subject: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Matthias Apitz List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 19:08:07 -0000 Hello, I'm used to connect my FreeBSD 10-CURRENT netbook to Internet via PPP; the provider in question is a German O2 UMTS provider; so far so good, i.e. all is working as it should: outbound HTTP, SSH, SMTP (I'm just sending this mail through such a connection), ... what does not work is VoIP; the call is established via SIP (using a STUN server), but remote audio RTP packages are not coming down; I checked this with TCPDUMP: only upstream RTP is send, no incoming UDP; as well I checked incoming TCP, for example incoming SSH or HTTP; it seems that incoming UCP/TCP is just not coming through the PPP link; before bother (complain) the provider with this, I wanted to ask if I miss something in the PPP configuration to get incoming delivered; note: I'm not talking about NAT to some stations on a LAN, I just want get IP to the local host (interface tun6); as well I disabled ipf(8) which I have configured normaly; any ideas? thanks in advance matthias -- Matthias Apitz e - w http://www.unixarea.de/ UNIX since V7 on PDP-11, UNIX on mainframe since ESER 1055 (IBM /370) UNIX on x86 since SVR4.2 UnixWare 2.1.2, FreeBSD since 2.2.5 From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 22:19:32 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9043E1065672; Tue, 17 Jan 2012 22:19:32 +0000 (UTC) (envelope-from pyunyh@gmail.com) Received: from mail-iy0-f182.google.com (mail-iy0-f182.google.com [209.85.210.182]) by mx1.freebsd.org (Postfix) with ESMTP id 4A8008FC19; Tue, 17 Jan 2012 22:19:32 +0000 (UTC) Received: by iagz16 with SMTP id z16so8872415iag.13 for ; Tue, 17 Jan 2012 14:19:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:date:to:cc:subject:message-id:reply-to:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=Ueutl+oehWuYOSXV0MOVkhu0wxvQQ7L7piSN0/Hjmdo=; b=XlbSoblqKCrf1fUGZiR1M2Bw13qUGnhFYDSK1OXnnDzjVA5qEfTDwoLTNm6paazAdU IFnGFV4Eq2A/7+mwjJN5RmY414WCsQKoAEyWYRf0qajvP0pRKKD3L1LUONg/csF1+PUd PTIQbEhjRWRk2uVH0y+/EdBJl9MNfYr1ov6SM= Received: by 10.50.182.130 with SMTP id ee2mr19293284igc.30.1326838771709; Tue, 17 Jan 2012 14:19:31 -0800 (PST) Received: from pyunyh@gmail.com ([174.35.1.224]) by mx.google.com with ESMTPS id h9sm81600129ibh.11.2012.01.17.14.19.29 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Jan 2012 14:19:31 -0800 (PST) Received: by pyunyh@gmail.com (sSMTP sendmail emulation); Tue, 17 Jan 2012 14:19:29 -0800 From: YongHyeon PYUN Date: Tue, 17 Jan 2012 14:19:29 -0800 To: John Baldwin Message-ID: <20120117221929.GA7469@michelle.cdnetworks.com> References: <1326560151.30035.YahooMailNeo@web36505.mail.mud.yahoo.com> <20120114225358.GA22889@michelle.cdnetworks.com> <201201171012.23725.jhb@freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <201201171012.23725.jhb@freebsd.org> User-Agent: Mutt/1.4.2.3i Cc: "freebsd-net@freebsd.org" , Bill Norton Subject: Re: bge0 interface seen but not working X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: pyunyh@gmail.com List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 22:19:32 -0000 On Tue, Jan 17, 2012 at 10:12:23AM -0500, John Baldwin wrote: > On Saturday, January 14, 2012 5:53:58 pm YongHyeon PYUN wrote: > > On Sat, Jan 14, 2012 at 08:55:51AM -0800, Bill Norton wrote: > > > Greetings, > > > > > > I posted this on the pc-bsd forum and was directed here.? > > > > > > I installed the latest 8.X and the interface worked fine.? > > > > > > Yesterday, I did a clean install of 9.0.? > > > > > > The issue is that the bge0 interface is not working.? > > > It is seen by the kernel(ifconfig shows it) but just won't ping. > > > I have tried dhcp and a static address.? > > > I used a backtrack live cd and this worked fine.? > > > > > > > Probably disabling MSI will workaround your issue. Add > > > > hw.pci.enable_msi="0" > > > > to /boot/loader.conf. > > > > > > > > I did find this bug below but it seemed to only affect 8.2 > > > > > > The bge(4) Ethernet driver has a known issue where the interface is seen > but does not respond to networking requests. A patch is available for 8.2 (see > 155442) and the driver will be fixed in 8.3. > > > > > > Any ideas?? > > > > > > > I thought it was already fixed by John but it seems it is not. > > John, would you take a look?(NVIDIA HT MSI issue)? > > It is not fully resolved. 9 has some different changes, but those changes > broke other systems. It seems MSI on NVIDIA HT systems requires a lot of > extra quirks to actually work. > Ok, to mitigate the issue, I introduced a tunable that disables MSI. Thanks. From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 22:59:45 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7B3A71065676 for ; Tue, 17 Jan 2012 22:59:45 +0000 (UTC) (envelope-from milu@dat.pl) Received: from jab.dat.pl (dat.pl [80.51.155.34]) by mx1.freebsd.org (Postfix) with ESMTP id 389E28FC0C for ; Tue, 17 Jan 2012 22:59:44 +0000 (UTC) Received: from jab.dat.pl (jsrv.dat.pl [127.0.0.1]) by jab.dat.pl (Postfix) with ESMTP id 975FD5F; Tue, 17 Jan 2012 23:43:40 +0100 (CET) X-Virus-Scanned: amavisd-new at dat.pl Received: from jab.dat.pl ([127.0.0.1]) by jab.dat.pl (jab.dat.pl [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 1hw2Yi8sQnjX; Tue, 17 Jan 2012 23:43:37 +0100 (CET) Received: from snifi.localnet (178-36-164-36.adsl.inetia.pl [178.36.164.36]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by jab.dat.pl (Postfix) with ESMTPSA id E8ECD2C; Tue, 17 Jan 2012 23:43:36 +0100 (CET) From: Maciej Milewski To: freebsd-net@freebsd.org, Matthias Apitz Date: Tue, 17 Jan 2012 23:43:15 +0100 Message-ID: <1784936.VLDeoQkidl@snifi> User-Agent: KMail/4.7.4 (Linux/3.1.9-2-ARCH; KDE/4.7.4; x86_64; ; ) In-Reply-To: <20120117190847.GA1255@tiny> References: <20120117190847.GA1255@tiny> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Cc: Subject: Re: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 22:59:45 -0000 Dnia wtorek, 17 stycznia 2012 20:08:48 Matthias Apitz pisze: > Hello, > > I'm used to connect my FreeBSD 10-CURRENT netbook to Internet via PPP; > the provider in question is a German O2 UMTS provider; so far so good, > i.e. all is working as it should: outbound HTTP, SSH, SMTP (I'm just > sending this mail through such a connection), ... > > what does not work is VoIP; the call is established via SIP (using a > STUN server), but remote audio RTP packages are not coming down; I > checked this with TCPDUMP: only upstream RTP is send, no incoming UDP; I observed similar problem with L2TP VPN and for me it looks that they are blocking incoming/returning UDP traffic in public APN. On the server side I see both incoming and outgoing traffic but device complains that it's unable to connect. If I switch to local wireless network then everthing works fine. I suspect that's because they are selling special(money) APNs. > as well I checked incoming TCP, for example incoming SSH or HTTP; it > seems that incoming UCP/TCP is just not coming through the PPP link; > > before bother (complain) the provider with this, I wanted to ask if I > miss something in the PPP configuration to get incoming delivered; > > note: I'm not talking about NAT to some stations on a LAN, I just want > get IP to the local host (interface tun6); as well I disabled ipf(8) > which I have configured normaly; > > any ideas? thanks in advance > > matthias -- Maciej Milewski From owner-freebsd-net@FreeBSD.ORG Tue Jan 17 23:28:17 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4B8F1106568B for ; Tue, 17 Jan 2012 23:28:17 +0000 (UTC) (envelope-from mike@mail.karels.net) Received: from mail.karels.net (mail.karels.net [63.231.190.5]) by mx1.freebsd.org (Postfix) with ESMTP id DB29F8FC21 for ; Tue, 17 Jan 2012 23:28:16 +0000 (UTC) Received: from mail.karels.net (localhost [127.0.0.1]) by mail.karels.net (8.14.3/8.13.6) with ESMTP id q0HN1pSk039205; Tue, 17 Jan 2012 17:01:51 -0600 (CST) (envelope-from mike@mail.karels.net) Message-Id: <201201172301.q0HN1pSk039205@mail.karels.net> To: freebsd-net@freebsd.org Date: Tue, 17 Jan 2012 17:01:51 -0600 From: Mike Karels Cc: mike_karels@mcafee.com Subject: Broadcom 10Gbps Ethernet driver (bxe) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 23:28:17 -0000 Has anyone had any success using the bxe driver with FreeBSD 9.0 or pre-releases? If so, are you using BCM57710 or BCM57711[E]? We are trying to use the 57710 without any success; it does not receive unicast packets, just broadcast or multicast. Thanks, Mike From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 01:07:33 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3A295106564A; Wed, 18 Jan 2012 01:07:33 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 0FA508FC12; Wed, 18 Jan 2012 01:07:33 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0I17WC2010764; Wed, 18 Jan 2012 01:07:32 GMT (envelope-from linimon@freefall.freebsd.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0I17W6j010760; Wed, 18 Jan 2012 01:07:32 GMT (envelope-from linimon) Date: Wed, 18 Jan 2012 01:07:32 GMT Message-Id: <201201180107.q0I17W6j010760@freefall.freebsd.org> To: linimon@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-net@FreeBSD.org From: linimon@FreeBSD.org Cc: Subject: Re: kern/164265: [netinet] [patch] tcp_lro_rx computes wrong checksum if 'csum' variable is 0 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 01:07:33 -0000 Old Synopsis: tcp_lro_rx computes wrong checksum if 'csum' variable is 0 New Synopsis: [netinet] [patch] tcp_lro_rx computes wrong checksum if 'csum' variable is 0 Responsible-Changed-From-To: freebsd-bugs->freebsd-net Responsible-Changed-By: linimon Responsible-Changed-When: Wed Jan 18 01:06:41 UTC 2012 Responsible-Changed-Why: Over to maintainer(s). http://www.freebsd.org/cgi/query-pr.cgi?pr=164265 From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 06:35:54 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 80899106564A for ; Wed, 18 Jan 2012 06:35:54 +0000 (UTC) (envelope-from guru@unixarea.de) Received: from ms16-1.1blu.de (ms16-1.1blu.de [89.202.0.34]) by mx1.freebsd.org (Postfix) with ESMTP id 107F58FC0A for ; Wed, 18 Jan 2012 06:35:53 +0000 (UTC) Received: from [88.217.30.188] (helo=localhost.my.domain) by ms16-1.1blu.de with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1RnP7f-0003T2-W7; Wed, 18 Jan 2012 07:35:52 +0100 Received: from localhost.my.domain (localhost [127.0.0.1]) by localhost.my.domain (8.14.4/8.14.3) with ESMTP id q0I6Zo7e002768; Wed, 18 Jan 2012 07:35:50 +0100 (CET) (envelope-from guru@unixarea.de) Received: (from guru@localhost) by localhost.my.domain (8.14.4/8.14.3/Submit) id q0I6Znqf002767; Wed, 18 Jan 2012 07:35:49 +0100 (CET) (envelope-from guru@unixarea.de) X-Authentication-Warning: localhost.my.domain: guru set sender to guru@unixarea.de using -f Date: Wed, 18 Jan 2012 07:35:49 +0100 From: Matthias Apitz To: Maciej Milewski Message-ID: <20120118063549.GA2742@tinyCurrent> References: <20120117190847.GA1255@tiny> <1784936.VLDeoQkidl@snifi> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1784936.VLDeoQkidl@snifi> X-Operating-System: FreeBSD 9.0-CURRENT r214444 (i386) User-Agent: Mutt/1.5.21 (2010-09-15) X-Con-Id: 51246 X-Originating-IP: 88.217.30.188 Cc: freebsd-net@freebsd.org Subject: Re: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Matthias Apitz List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 06:35:54 -0000 El día Tuesday, January 17, 2012 a las 11:43:15PM +0100, Maciej Milewski escribió: > Dnia wtorek, 17 stycznia 2012 20:08:48 Matthias Apitz pisze: > > Hello, > > > > I'm used to connect my FreeBSD 10-CURRENT netbook to Internet via PPP; > > the provider in question is a German O2 UMTS provider; so far so good, > > i.e. all is working as it should: outbound HTTP, SSH, SMTP (I'm just > > sending this mail through such a connection), ... > > > > what does not work is VoIP; the call is established via SIP (using a > > STUN server), but remote audio RTP packages are not coming down; I > > checked this with TCPDUMP: only upstream RTP is send, no incoming UDP; > I observed similar problem with L2TP VPN and for me it looks that they are > blocking incoming/returning UDP traffic in public APN. > On the server side I see both incoming and outgoing traffic but device > complains that it's unable to connect. If I switch to local wireless network > then everthing works fine. I suspect that's because they are selling > special(money) APNs. Thanks for your feedback; I think too, that UDP downstream is blocked if there is not upstream UDP initialized for the same socket pair; and VoIP is using different UDP ports for up- and downstream media (audio). What I'm wondering is, how does Skype works (which is fine with my UMTS provider at the same time), have to check this with TCPDUMP... matthias -- Matthias Apitz t +49-89-61308 351 - f +49-89-61308 399 - m +49-170-4527211 e - w http://www.unixarea.de/ UNIX since V7 on PDP-11 | UNIX on mainframe since ESER 1055 (IBM /370) UNIX on x86 since SVR4.2 UnixWare 2.1.2 | FreeBSD since 2.2.5 From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 08:15:45 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4B70E1065670 for ; Wed, 18 Jan 2012 08:15:45 +0000 (UTC) (envelope-from guru@unixarea.de) Received: from ms16-1.1blu.de (ms16-1.1blu.de [89.202.0.34]) by mx1.freebsd.org (Postfix) with ESMTP id 05D438FC13 for ; Wed, 18 Jan 2012 08:15:44 +0000 (UTC) Received: from [82.113.99.77] (helo=tiny.Sisis.de) by ms16-1.1blu.de with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1RnQgH-0004bG-TZ; Wed, 18 Jan 2012 09:15:42 +0100 Received: from tiny.Sisis.de (localhost [127.0.0.1]) by tiny.Sisis.de (8.14.5/8.14.3) with ESMTP id q0I8GS2R001280; Wed, 18 Jan 2012 09:16:28 +0100 (CET) (envelope-from guru@unixarea.de) Received: (from guru@localhost) by tiny.Sisis.de (8.14.5/8.14.3/Submit) id q0I8GRZ9001279; Wed, 18 Jan 2012 09:16:27 +0100 (CET) (envelope-from guru@unixarea.de) X-Authentication-Warning: tiny.Sisis.de: guru set sender to guru@unixarea.de using -f Date: Wed, 18 Jan 2012 09:16:26 +0100 From: Matthias Apitz To: volker@vwsoft.com Message-ID: <20120118081626.GA1267@tiny> References: <20120117190847.GA1255@tiny> <4F167E00.9040601@vwsoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <4F167E00.9040601@vwsoft.com> X-Operating-System: FreeBSD 10.0-CURRENT r226986 (i386) User-Agent: Mutt/1.5.21 (2010-09-15) X-Con-Id: 51246 X-Originating-IP: 82.113.99.77 Cc: freebsd-net@freebsd.org Subject: Re: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Matthias Apitz List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 08:15:45 -0000 El día Wednesday, January 18, 2012 a las 09:08:32AM +0100, volker@vwsoft.com escribió: > Matthias, > > can you please check the IP address you're getting from your mobile > network provider? AFAICT most hand out IPv4 addresses from private > network address space (RFC-1918). > > For some European countries I can tell, I've never seen routable > addresses being used on 3G networks. That might be the most likely cause > of your trouble. Hi Volker, The interface looks like this: # ifconfig tun6 tun6: flags=8051 metric 0 mtu 1500 options=80000 inet 10.63.255.77 --> 10.64.64.64 netmask 0xffffffff nd6 options=21 Opened by PID 1041 but the WAN addr is valid (seems to be NAT'ed) in the APN: # lynx -dump myip.nl | fgrep WAN WAN IP adres: 82.113.99.77 Thanks matthias -- Matthias Apitz e - w http://www.unixarea.de/ UNIX since V7 on PDP-11, UNIX on mainframe since ESER 1055 (IBM /370) UNIX on x86 since SVR4.2 UnixWare 2.1.2, FreeBSD since 2.2.5 From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 08:30:08 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77B81106566C for ; Wed, 18 Jan 2012 08:30:08 +0000 (UTC) (envelope-from volker@vwsoft.com) Received: from gwmbg.elbekies.net (gwmbg.elbekies.net [217.6.211.147]) by mx1.freebsd.org (Postfix) with ESMTP id 22EE28FC16 for ; Wed, 18 Jan 2012 08:30:07 +0000 (UTC) Received: from bel.soho.vwsoft.com (p57A0CD4B.dip.t-dialin.net [87.160.205.75]) (Authenticated sender: relay@elbekies.net) by gwmbg.elbekies.net (Postfix) with ESMTPA id 878232FA; Wed, 18 Jan 2012 09:10:41 +0100 (CET) Received: from [192.168.16.4] (dardanos.sz.vwsoft.com [192.168.16.4]) by bel.soho.vwsoft.com (Postfix) with ESMTP id E686E33CA0; Wed, 18 Jan 2012 09:08:32 +0100 (CET) Message-ID: <4F167E00.9040601@vwsoft.com> Date: Wed, 18 Jan 2012 09:08:32 +0100 From: volker@vwsoft.com User-Agent: Mozilla/5.0 (X11; FreeBSD i386; rv:9.0) Gecko/20111222 Thunderbird/9.0 MIME-Version: 1.0 To: Matthias Apitz References: <20120117190847.GA1255@tiny> In-Reply-To: <20120117190847.GA1255@tiny> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-MailScanner-ID: E686E33CA0.A0E1E X-VWSoft-MailScanner: Found to be clean X-MailScanner-From: volker@vwsoft.com X-MailScanner-To: freebsd-net@freebsd.org, guru@unixarea.de MailScanner-NULL-Check: 1327478922.13662@Rwup9beXuXJnfXpM3AucNQ Cc: freebsd-net@freebsd.org Subject: Re: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 08:30:08 -0000 On 01/17/12 20:08, Matthias Apitz wrote: > > Hello, > > I'm used to connect my FreeBSD 10-CURRENT netbook to Internet via PPP; > the provider in question is a German O2 UMTS provider; so far so good, > i.e. all is working as it should: outbound HTTP, SSH, SMTP (I'm just > sending this mail through such a connection), ... > > what does not work is VoIP; the call is established via SIP (using a > STUN server), but remote audio RTP packages are not coming down; I > checked this with TCPDUMP: only upstream RTP is send, no incoming UDP; > > as well I checked incoming TCP, for example incoming SSH or HTTP; it > seems that incoming UCP/TCP is just not coming through the PPP link; > > before bother (complain) the provider with this, I wanted to ask if I > miss something in the PPP configuration to get incoming delivered; > > note: I'm not talking about NAT to some stations on a LAN, I just want > get IP to the local host (interface tun6); as well I disabled ipf(8) > which I have configured normaly; > > any ideas? thanks in advance > > matthias Matthias, can you please check the IP address you're getting from your mobile network provider? AFAICT most hand out IPv4 addresses from private network address space (RFC-1918). For some European countries I can tell, I've never seen routable addresses being used on 3G networks. That might be the most likely cause of your trouble. All the best, Volker From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 09:05:30 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 701CE106566C for ; Wed, 18 Jan 2012 09:05:30 +0000 (UTC) (envelope-from milu@dat.pl) Received: from jab.dat.pl (dat.pl [80.51.155.34]) by mx1.freebsd.org (Postfix) with ESMTP id 270A48FC1A for ; Wed, 18 Jan 2012 09:05:29 +0000 (UTC) Received: from jab.dat.pl (jsrv.dat.pl [127.0.0.1]) by jab.dat.pl (Postfix) with ESMTP id 8D6537A; Wed, 18 Jan 2012 10:05:28 +0100 (CET) X-Virus-Scanned: amavisd-new at dat.pl Received: from jab.dat.pl ([127.0.0.1]) by jab.dat.pl (jab.dat.pl [127.0.0.1]) (amavisd-new, port 10024) with LMTP id d-v1ls9kf99U; Wed, 18 Jan 2012 10:05:23 +0100 (CET) Received: from snifi.localnet (unknown [212.69.68.42]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by jab.dat.pl (Postfix) with ESMTPSA id CA6A651; Wed, 18 Jan 2012 10:05:23 +0100 (CET) From: Maciej Milewski To: Matthias Apitz Date: Wed, 18 Jan 2012 10:05:26 +0100 Message-ID: <7227503.Fd8S0FJ3Ep@snifi> User-Agent: KMail/4.7.4 (Linux/3.1.9-2-ARCH; KDE/4.7.4; x86_64; ; ) In-Reply-To: <20120118063549.GA2742@tinyCurrent> References: <20120117190847.GA1255@tiny> <1784936.VLDeoQkidl@snifi> <20120118063549.GA2742@tinyCurrent> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Cc: freebsd-net@freebsd.org Subject: Re: PPP to UMTS provider && incoming traffic (TCP, UDP) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 09:05:30 -0000 Dnia =C5=9Broda, 18 stycznia 2012 07:35:49 Matthias Apitz pisze: > Thanks for your feedback; I think too, that UDP downstream is blocked= if > there is not upstream UDP initialized for the same socket pair; and V= oIP > is using different UDP ports for up- and downstream media (audio). >=20 > What I'm wondering is, how does Skype works (which is fine with my UM= TS > provider at the same time), have to check this with TCPDUMP... >=20 > =09matthias Skype according to wikipedia[1] uses such scenario: 1. start 2. send UDP packet(s) to HC 3. if no response within 5 seconds then 4. attempt TCP connection with HC 5. if not connected then 6. attempt TCP connection with HC on port 80 (HTTP) 7. if not connected then 8. attempt TCP connection with HC on port 443 (HTTPS) 9. if not connected then 10. attempts++ 11. if attempts=3D=3D5 then 12. fail 13. else 14. wait 6 seconds 15. goto step 2 16. Success So it uses TCP and to obey blocked ports uses www traffic ports: 80 and= 443. [1] http://en.wikipedia.org/wiki/Skype_protocol --=20 Maciej Milewski From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 10:11:25 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4860A106566C for ; Wed, 18 Jan 2012 10:11:25 +0000 (UTC) (envelope-from kang.chen@nsn.com) Received: from demumfd002.nsn-inter.net (demumfd002.nsn-inter.net [93.183.12.31]) by mx1.freebsd.org (Postfix) with ESMTP id AC45C8FC16 for ; Wed, 18 Jan 2012 10:11:24 +0000 (UTC) Received: from demuprx017.emea.nsn-intra.net ([10.150.129.56]) by demumfd002.nsn-inter.net (8.12.11.20060308/8.12.11) with ESMTP id q0I9bdSd019454 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 18 Jan 2012 10:37:42 +0100 Received: from demuexc024.nsn-intra.net (demuexc024.nsn-intra.net [10.159.32.11]) by demuprx017.emea.nsn-intra.net (8.12.11.20060308/8.12.11) with ESMTP id q0I9bbl3020867 for ; Wed, 18 Jan 2012 10:37:39 +0100 Received: from CNBEEXC006.nsn-intra.net ([10.159.192.11]) by demuexc024.nsn-intra.net with Microsoft SMTPSVC(6.0.3790.4675); Wed, 18 Jan 2012 10:37:21 +0100 X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Date: Wed, 18 Jan 2012 17:36:04 +0800 Message-ID: <4E06CB69D1F4FE48911C9CAB689E2B01025F8219@CNBEEXC006.nsn-intra.net> In-Reply-To: <20120117190847.GA1255@tiny> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: How to change vlan id without destroy and recreate a new vlan Thread-Index: AczVS27IIbKwSFBVTxappgwE08o4HQAeDbwg References: <20120117190847.GA1255@tiny> From: "Chen, Kang (NSN - CN/Hangzhou)" To: X-OriginalArrivalTime: 18 Jan 2012 09:37:21.0513 (UTC) FILETIME=[C6F4A590:01CCD5C4] Subject: How to change vlan id without destroy and recreate a new vlan X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 10:11:25 -0000 Hello, As you know, if I want to create a new vlan interface face, I can use the following command: ifconfig vlan0 vlan 101 vlandev fxp0 My question is, if I want to change the vlan id 101 to 202, if there anyway to do this without destroy it and recreate? BR, CK 2012-1-18 From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 10:23:30 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 79D811065674 for ; Wed, 18 Jan 2012 10:23:30 +0000 (UTC) (envelope-from guru@unixarea.de) Received: from ms16-1.1blu.de (ms16-1.1blu.de [89.202.0.34]) by mx1.freebsd.org (Postfix) with ESMTP id 2EDCB8FC08 for ; Wed, 18 Jan 2012 10:23:29 +0000 (UTC) Received: from [82.113.99.8] (helo=tiny.Sisis.de) by ms16-1.1blu.de with esmtpsa (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1RnSfv-0005C1-P5; Wed, 18 Jan 2012 11:23:28 +0100 Received: from tiny.Sisis.de (localhost [127.0.0.1]) by tiny.Sisis.de (8.14.5/8.14.3) with ESMTP id q0IAOEwT001142; Wed, 18 Jan 2012 11:24:14 +0100 (CET) (envelope-from guru@unixarea.de) Received: (from guru@localhost) by tiny.Sisis.de (8.14.5/8.14.3/Submit) id q0IAODDu001141; Wed, 18 Jan 2012 11:24:13 +0100 (CET) (envelope-from guru@unixarea.de) X-Authentication-Warning: tiny.Sisis.de: guru set sender to guru@unixarea.de using -f Date: Wed, 18 Jan 2012 11:24:13 +0100 From: Matthias Apitz To: "Chen, Kang (NSN - CN/Hangzhou)" Message-ID: <20120118102412.GA1134@tiny> References: <20120117190847.GA1255@tiny> <4E06CB69D1F4FE48911C9CAB689E2B01025F8219@CNBEEXC006.nsn-intra.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <4E06CB69D1F4FE48911C9CAB689E2B01025F8219@CNBEEXC006.nsn-intra.net> X-Operating-System: FreeBSD 10.0-CURRENT r226986 (i386) User-Agent: Mutt/1.5.21 (2010-09-15) X-Con-Id: 51246 X-Originating-IP: 82.113.99.8 Cc: freebsd-net@freebsd.org Subject: Re: How to change vlan id without destroy and recreate a new vlan X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Matthias Apitz List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 10:23:30 -0000 El día Wednesday, January 18, 2012 a las 05:36:04PM +0800, Chen, Kang (NSN - CN/Hangzhou) escribió: > Hello, > > ... Please don't high-jack a thread by replying to a mail of me and just changing the Subject: to your needs; thanks in advance for paying attention matthias -- Matthias Apitz e - w http://www.unixarea.de/ UNIX since V7 on PDP-11, UNIX on mainframe since ESER 1055 (IBM /370) UNIX on x86 since SVR4.2 UnixWare 2.1.2, FreeBSD since 2.2.5 From owner-freebsd-net@FreeBSD.ORG Wed Jan 18 10:25:01 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5A6C5106566C for ; Wed, 18 Jan 2012 10:25:01 +0000 (UTC) (envelope-from freebsd-net@dino.sk) Received: from loki.netlab.sk (loki.netlab.sk [84.245.65.11]) by mx1.freebsd.org (Postfix) with ESMTP id B0A908FC16 for ; Wed, 18 Jan 2012 10:25:00 +0000 (UTC) Received: from atom.dino.sk (fw1.dino.sk [84.245.95.252]) (AUTH: LOGIN milan, TLS: TLSv1/SSLv3,128bits,AES128-SHA) by loki.netlab.sk with ESMTPSA; Wed, 18 Jan 2012 11:13:20 +0100 id 00033CD7.4F169B40.00014351 Date: Wed, 18 Jan 2012 11:14:45 +0100 From: Milan Obuch To: freebsd-net@freebsd.org Message-ID: <20120118111445.7c131376@atom.dino.sk> In-Reply-To: <4E06CB69D1F4FE48911C9CAB689E2B01025F8219@CNBEEXC006.nsn-intra.net> References: <20120117190847.GA1255@tiny> <4E06CB69D1F4FE48911C9CAB689E2B01025F8219@CNBEEXC006.nsn-intra.net> X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.6; amd64-portbld-freebsd8.2) Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEX+/v7++v6YOTrq8PCcuIX989UvOSj++v0BNCbpAAAAB3RJTUUHsQwfFzs7RBhzUQAAAhJJREFUOI1dU8GOqzAMNKIoV1bvwD1i0ysqrHplIdBrVSX7ATSbd03VVvn9tQNtQy0hjAdn7LED4AAcPtWm9RV+MPSfxhBLx9ajd6X/ngB6/mTwnRSZua7i7Ca+0ctZKo4Qmz+JY13X6I3nFZBxIYW1PbgfQ5RP8g0XlltEWGf3cV03joYpRnFbvYDKbXjZlXyyhEZA4lI+cN3NaVXE4VKjSwTExO10eTEkkJVqIAD5z0nUBQJluQDRSQjcrBiHAJxZlAH5CUMBMC7OcJ4LMQNnxhZ1HYPscMc6J4UlWRMNwzOpCcAHKSICd1EDn83abdREIbXsHkD1OinP1aCUCOEVRaa1lMcvywUWdYgk13JQUpYNKmvXQ8Kw5ML9YI5h8SakctBc7E/IYuLhYd/zZIk+1gM1vNweQBvHE0j+oYah3sMqAytQYlZk6+ANaaawJdu3OFzYGMZ3iGpa3qMlq9ZH0VZTgrCtw/ngdYkEIIpSbP1bWQAdFdX9vocBdkH2qVjVmuMu3gI5rjs814EUdrCZgWlPaxZZ3RiLFUtr+ud0PXwp2dnQSNXgePt6AZpBj6UMJ7VQkzN4utVeaSW1Dhn/kblGrKeMvNGnzwX4zuEDarYz1KdPtR60Gul0Gued+515SJXhCsl+Tx/3kY/UDvicPll9mfu50t3tvQ/thZpJYgeuwdSKNJ6tCD98MCgoxLDaPxbwqqwPWaWiAAAAAElFTkSuQmCC X-Face: ak5rwz4-aUa>hPFZlcg,bXxn.(TN}e9DGFrKU\.i_'B[&5=pAd9o"j)5VSUYW:BRQG#^42Ev$Il|; Ztn=,C X-Operating-System: FreeBSD/amd64 8.2-STABLE Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: How to change vlan id without destroy and recreate a new vlan X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2012 10:25:01 -0000 On Wed, 18 Jan 2012 17:36:04 +0800 "Chen, Kang (NSN - CN/Hangzhou)" wrote: > Hello, > > As you know, if I want to create a new vlan interface face, I can use > the following command: > ifconfig vlan0 vlan 101 vlandev fxp0 > My question is, if I want to change the vlan id 101 to 202, if there > anyway to do this without destroy it and recreate? > Hi, I did it sometimes with following command sequence: ifconfig vlan0 -vlandev fxp0 ifconfig vlan0 vlan 202 vlandev fxp0 (writing off top of my head, but generally that's just it) Regards, Milan From owner-freebsd-net@FreeBSD.ORG Thu Jan 19 07:10:12 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 996181065670 for ; Thu, 19 Jan 2012 07:10:12 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 834FD8FC15 for ; Thu, 19 Jan 2012 07:10:12 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0J7ACDS026127 for ; Thu, 19 Jan 2012 07:10:12 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0J7ACKR026122; Thu, 19 Jan 2012 07:10:12 GMT (envelope-from gnats) Date: Thu, 19 Jan 2012 07:10:12 GMT Message-Id: <201201190710.q0J7ACKR026122@freefall.freebsd.org> To: freebsd-net@FreeBSD.org From: =?windows-1251?B?yu7t/Oru4iDF4uPl7ejp?= Cc: Subject: Re: kern/163482: IP address is not round robined if DNS name has many IPs X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: =?windows-1251?B?yu7t/Oru4iDF4uPl7ejp?= List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jan 2012 07:10:12 -0000 The following reply was made to PR kern/163482; it has been noted by GNATS. From: =?windows-1251?B?yu7t/Oru4iDF4uPl7ejp?= To: bug-followup@FreeBSD.org, kes-kes@yandex.ru Cc: Subject: Re: kern/163482: IP address is not round robined if DNS name has many IPs Date: Thu, 19 Jan 2012 09:07:20 +0200 Answer from: Mark Andrews via RT 3261. [func] RRset ordering now defaults to random. [RT #27174] 3260. [bug] "rrset-order cyclic" could appear not to rotate for some query patterns. [RT #27170/27185] We committed a different fix to the one I sent you earlier. The above will be in 9.9.0 final. From owner-freebsd-net@FreeBSD.ORG Thu Jan 19 16:41:29 2012 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B0B321065686; Thu, 19 Jan 2012 16:41:29 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id 70A4A8FC27; Thu, 19 Jan 2012 16:41:29 +0000 (UTC) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [96.47.65.170]) by cyrus.watson.org (Postfix) with ESMTPSA id 2515646B06; Thu, 19 Jan 2012 11:41:29 -0500 (EST) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 851E2B922; Thu, 19 Jan 2012 11:41:28 -0500 (EST) From: John Baldwin To: net@freebsd.org Date: Thu, 19 Jan 2012 11:41:25 -0500 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p10; KDE/4.5.5; amd64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201201191141.25998.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Thu, 19 Jan 2012 11:41:28 -0500 (EST) Cc: Ed Maste , Navdeep Parhar Subject: Latency issues with buf_ring X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jan 2012 16:41:29 -0000 The current buf_ring usage in various NIC drivers has a race that can result in really high packet latencies in some cases. Specifically, the common pattern in an if_transmit routine is to use a try-lock on the queue and if that fails enqueue the packet in the buf_ring and return. The race, of course, is that the thread holding the lock might have just finished checking the buf_ring and found it empty and be in the process of releasing the lock when the original thread fails the try lock. If this happens, then the packet queued by the first thread will be stalled until another thread tries to transmit packets for that queue. Some drivers attempt to handle this race (igb(4) schedules a task to kick the transmit queue if the try lock fails) and others don't (cxgb(4) doesn't handle it at all). At work this race was triggered very often after upgrading from 7 to 8 with bursty traffic and caused numerous problems, so it is not a rare occurrence and needs to be addressed. (Note, all patches mentioned are against 8) The first hack I tried to use was to simply always lock the queue after the drbr enqueue if the try lock failed and then drain the queue if needed (www.freebsd.org/~jhb/patches/try_fail.patch). While this fixed my latency problems, it would seem that this breaks other workloads that the drbr design is trying to optimize. After further hacking what I came up with was a variant of drbr_enqueue() that would atomically set a 'pending' flag. During the enqueue operation. The first thread to fail the try lock sets this flag (it is told that it set the flag by a new return value (EINPROGRESS) from the enqueue call). The pending thread then explicitly clears the flag once it acquires the queue lock. This should prevent multiple threads from stacking up on the queue lock so that if multiple threads are dumping packets into the ring concurrently all but two (the one draining the queue currently and the one waiting for the lock) can continue to drain the queue. One downside of this approach though is that each driver has to be changed to make an explicit call to clear the pending flag after grabbing the queue lock if the try lock fails. This is what I am currently running in production (www.freebsd.org/~jhb/patches/try_fail3.patch). However, this still results in a lot of duplicated code in each driver that wants to support multiq. Several folks have expressed a desire to move in a direction where the stack has explicit knowledge of transmit queues allowing us to hoist some of this duplicated code out of the drivers and up into the calling layer. After discussing this a bit with Navdeep (np@), the approach I am looking at is to alter the buf_ring code flow a bit to more closely model the older code-flow with IFQ and if_start methods. That is, have the if_transmit methods always enqueue each packet that arrives to the buf_ring and then to call an if_start-like method that drains a specific transmit queue. This approach simplifies a fair bit of driver code and means we can potentially move the enqueue, etc. bits up into the calling layer and instead have drivers provide the per-transmit queue start routine as the direct function pointer to the upper layers ala if_start. However, we would still need a way to close the latency race. I've attempted to do that by inverting my previous 'thread pending' flag. Instead, I make the buf_ring store a 'busy' flag. This flag is managed by the single-consumer buf_ring dequeue method (that drbr_dequeue() uses). It is set to true when a packet is removed from the queue while there are more packets pending. Conversely, if there are no other pending packets then it is set to false. The assumption is that once a thread starts draining the queue, it will not stop until the queue is empty (or if it has to stop for some other reason such as the transmit ring being full, the driver will restart draining of the queue until it is empty, e.g. after it receives a transmit completion interrupt). Now when the if_transmit routine enqueues the packet, it will get either a real error, 0 if the packet was enqueued and the queue was not idle, or EINPROGRESS if the packet was enqueued and the queue was busy. For the EINPROGRESS case the if_transmit routine just returns success. For the 0 case it does a blocking lock on the queue lock and calls the queue's start routine (note that this means that the busy flag is similar to the old OACTIVE interface flag). This does mean that in some cases you may have one thread that is sending what was the last packet in the buf_ring holding the lock when another thread blocks, and that the first thread will see the new packet when it loops back around so that the second thread is wasting it's time spinning, but in the common case I believe it will give the same parallelism as the current code. OTOH, there is nothing to prevent multiple threads from "stacking up" in the new approach. At least the try_fail3 patch ensured only one thread at a time would ever potentially block on the queue lock. Another approach might be to replace the 'busy' flag with the 'thread pending' flag from try_fail3.patch, but to clear the 'thread pending' flag anytime the dequeue method is called rather than using an explicit 'clear pending' method. (Hadn't thought of that until writing this e-mail.) That would prevent multiple threads from waiting on the queue lock perhaps. Note that the 'busy' approach (or the modification I mentioned above) does rely on the assumption I stated above, i.e. once a driver starts draining a queue, it will drain it until empty unless it hits an "error" condition (link went down, transmit ring full, etc.). If it hits an "error" condition, the driver is responsible for restarting transmit when the condition clears. I believe our drivers already work this way now. The 'busy' patch is at http://www.freebsd.org/~jhb/patches/drbr.patch -- John Baldwin From owner-freebsd-net@FreeBSD.ORG Thu Jan 19 18:35:26 2012 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07D0F1065672; Thu, 19 Jan 2012 18:35:26 +0000 (UTC) (envelope-from jfvogel@gmail.com) Received: from mail-ww0-f42.google.com (mail-ww0-f42.google.com [74.125.82.42]) by mx1.freebsd.org (Postfix) with ESMTP id 383FD8FC12; Thu, 19 Jan 2012 18:35:24 +0000 (UTC) Received: by wgbgn7 with SMTP id gn7so5085426wgb.1 for ; Thu, 19 Jan 2012 10:35:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=7b/rVdCyI6HmNZE0Q2Yemg3ZCrNbWEoDLdArr8Ep3M0=; b=WOSOEk+Ttb0kJe5YO3ys0Y3V81TDAZbyGKdKbCCDN5QNdduOVDOcVrTCb5bssVCIim imiPEX9cAMh7wp5McRWC/s32HcgqD2C/gRoAGTnf2SkTXNbPaab7NolLezipkpU7ehMX gnBghJplY71rLfo0MOQEZew9L8VuUy9i1ZFW0= MIME-Version: 1.0 Received: by 10.180.106.202 with SMTP id gw10mr50598879wib.3.1326996310570; Thu, 19 Jan 2012 10:05:10 -0800 (PST) Received: by 10.180.84.66 with HTTP; Thu, 19 Jan 2012 10:05:10 -0800 (PST) In-Reply-To: <201201191141.25998.jhb@freebsd.org> References: <201201191141.25998.jhb@freebsd.org> Date: Thu, 19 Jan 2012 10:05:10 -0800 Message-ID: From: Jack Vogel To: John Baldwin Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Ed Maste , Navdeep Parhar , net@freebsd.org Subject: Re: Latency issues with buf_ring X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jan 2012 18:35:26 -0000 Interesting that you bring this up, I have just recently found that UDP TX stressing in my igb driver suffers when using the mq interface, using the old interface its much better, I've not been real happy about just reverting, my interim solution has been to make a compile option to the driver, but a REAL fix would be much appreciated!! Cheers, Jack On Thu, Jan 19, 2012 at 8:41 AM, John Baldwin wrote: > The current buf_ring usage in various NIC drivers has a race that can > result in really high packet latencies in some cases. Specifically, > the common pattern in an if_transmit routine is to use a try-lock on > the queue and if that fails enqueue the packet in the buf_ring and > return. The race, of course, is that the thread holding the lock > might have just finished checking the buf_ring and found it empty and > be in the process of releasing the lock when the original thread fails > the try lock. If this happens, then the packet queued by the first > thread will be stalled until another thread tries to transmit packets > for that queue. Some drivers attempt to handle this race (igb(4) > schedules a task to kick the transmit queue if the try lock fails) and > others don't (cxgb(4) doesn't handle it at all). At work this race > was triggered very often after upgrading from 7 to 8 with bursty > traffic and caused numerous problems, so it is not a rare occurrence > and needs to be addressed. > > (Note, all patches mentioned are against 8) > > The first hack I tried to use was to simply always lock the queue after > the drbr enqueue if the try lock failed and then drain the queue if > needed (www.freebsd.org/~jhb/patches/try_fail.patch). > While this fixed > my latency problems, it would seem that this breaks other workloads > that the drbr design is trying to optimize. > > After further hacking what I came up with was a variant of drbr_enqueue() > that would atomically set a 'pending' flag. During the enqueue operation. > The first thread to fail the try lock sets this flag (it is told that it > set the flag by a new return value (EINPROGRESS) from the enqueue call). > The pending thread then explicitly clears the flag once it acquires the > queue lock. This should prevent multiple threads from stacking up on the > queue lock so that if multiple threads are dumping packets into the ring > concurrently all but two (the one draining the queue currently and the > one waiting for the lock) can continue to drain the queue. One downside > of this approach though is that each driver has to be changed to make > an explicit call to clear the pending flag after grabbing the queue lock > if the try lock fails. This is what I am currently running in production > (www.freebsd.org/~jhb/patches/try_fail3.patch > ). > > However, this still results in a lot of duplicated code in each driver > that wants to support multiq. Several folks have expressed a desire > to move in a direction where the stack has explicit knowledge of > transmit queues allowing us to hoist some of this duplicated code out > of the drivers and up into the calling layer. After discussing this a > bit with Navdeep (np@), the approach I am looking at is to alter the > buf_ring code flow a bit to more closely model the older code-flow > with IFQ and if_start methods. That is, have the if_transmit methods > always enqueue each packet that arrives to the buf_ring and then to > call an if_start-like method that drains a specific transmit queue. > This approach simplifies a fair bit of driver code and means we can > potentially move the enqueue, etc. bits up into the calling layer and > instead have drivers provide the per-transmit queue start routine as > the direct function pointer to the upper layers ala if_start. > > However, we would still need a way to close the latency race. I've > attempted to do that by inverting my previous 'thread pending' flag. > Instead, I make the buf_ring store a 'busy' flag. This flag is > managed by the single-consumer buf_ring dequeue method (that > drbr_dequeue() uses). It is set to true when a packet is removed from > the queue while there are more packets pending. Conversely, if there > are no other pending packets then it is set to false. The assumption > is that once a thread starts draining the queue, it will not stop > until the queue is empty (or if it has to stop for some other reason > such as the transmit ring being full, the driver will restart draining > of the queue until it is empty, e.g. after it receives a transmit > completion interrupt). Now when the if_transmit routine enqueues the > packet, it will get either a real error, 0 if the packet was enqueued > and the queue was not idle, or EINPROGRESS if the packet was enqueued > and the queue was busy. For the EINPROGRESS case the if_transmit > routine just returns success. For the 0 case it does a blocking lock > on the queue lock and calls the queue's start routine (note that this > means that the busy flag is similar to the old OACTIVE interface > flag). This does mean that in some cases you may have one thread that > is sending what was the last packet in the buf_ring holding the lock > when another thread blocks, and that the first thread will see the new > packet when it loops back around so that the second thread is wasting > it's time spinning, but in the common case I believe it will give the > same parallelism as the current code. OTOH, there is nothing to > prevent multiple threads from "stacking up" in the new approach. At > least the try_fail3 patch ensured only one thread at a time would ever > potentially block on the queue lock. > > Another approach might be to replace the 'busy' flag with the 'thread > pending' flag from try_fail3.patch, but to clear the 'thread pending' > flag anytime the dequeue method is called rather than using an > explicit 'clear pending' method. (Hadn't thought of that until > writing this e-mail.) That would prevent multiple threads from > waiting on the queue lock perhaps. > > Note that the 'busy' approach (or the modification I mentioned above) > does rely on the assumption I stated above, i.e. once a driver starts > draining a queue, it will drain it until empty unless it hits an > "error" condition (link went down, transmit ring full, etc.). If it > hits an "error" condition, the driver is responsible for restarting > transmit when the condition clears. I believe our drivers already > work this way now. > > The 'busy' patch is at http://www.freebsd.org/~jhb/patches/drbr.patch > > -- > John Baldwin > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" > From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 01:42:01 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0DC41106566B; Fri, 20 Jan 2012 01:42:01 +0000 (UTC) (envelope-from dougb@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D74418FC20; Fri, 20 Jan 2012 01:42:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0K1g0fC000357; Fri, 20 Jan 2012 01:42:00 GMT (envelope-from dougb@freefall.freebsd.org) Received: (from dougb@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0K1g02O000347; Fri, 20 Jan 2012 01:42:00 GMT (envelope-from dougb) Date: Fri, 20 Jan 2012 01:42:00 GMT Message-Id: <201201200142.q0K1g02O000347@freefall.freebsd.org> To: kes-kes@yandex.ru, dougb@FreeBSD.org, freebsd-net@FreeBSD.org, dougb@FreeBSD.org From: dougb@FreeBSD.org Cc: Subject: Re: kern/163482: IP address is not round robined if DNS name has many IPs X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 01:42:01 -0000 Synopsis: IP address is not round robined if DNS name has many IPs State-Changed-From-To: open->closed State-Changed-By: dougb State-Changed-When: Fri Jan 20 01:40:42 UTC 2012 State-Changed-Why: Bug is fixed in later versions of BIND. The fix will be imported when it's available from the vendor. Doug Responsible-Changed-From-To: freebsd-net->dougb Responsible-Changed-By: dougb Responsible-Changed-When: Fri Jan 20 01:40:42 UTC 2012 Responsible-Changed-Why: BIND is my area. http://www.freebsd.org/cgi/query-pr.cgi?pr=163482 From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 07:11:07 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67924106566B for ; Fri, 20 Jan 2012 07:11:07 +0000 (UTC) (envelope-from bra@fsn.hu) Received: from people.fsn.hu (people.fsn.hu [195.228.252.137]) by mx1.freebsd.org (Postfix) with ESMTP id 196C28FC12 for ; Fri, 20 Jan 2012 07:11:06 +0000 (UTC) Received: by people.fsn.hu (Postfix, from userid 1001) id BC7F1B79AC1; Fri, 20 Jan 2012 07:52:48 +0100 (CET) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000002, version=1.2.2 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MF-ACE0E1EA [pR: 9.5271] X-CRM114-CacheID: sfid-20120120_07524_CDA0E4B9 X-CRM114-Status: Good ( pR: 9.5271 ) X-DSPAM-Result: Whitelisted X-DSPAM-Processed: Fri Jan 20 07:52:48 2012 X-DSPAM-Confidence: 0.6998 X-DSPAM-Probability: 0.0000 X-DSPAM-Signature: 4f190f40103572086412460 X-DSPAM-Factors: 27, From*Attila Nagy , 0.00010, FreeBSD, 0.00053, Is+there, 0.00574, there+any, 0.00708, rc, 0.00752, Date*07+52, 0.99000, not+having, 0.01000, sucks, 0.01000, hacking, 0.01000, way+which, 0.99000, Date*52+47, 0.99000, routing, 0.01000, routing, 0.01000, Are+there, 0.01000, User-Agent*i686, 0.01124, Subject*support, 0.01198, seems+to, 0.01260, User-Agent*Linux+i686, 0.01283, scripts, 0.01329, assume, 0.01329, User-Agent*i686+en, 0.01380, User-Agent*Mozilla/5.0+(X11, 0.01601, support+for, 0.01831, PR, 0.01873, stable, 0.01929, table, 0.01981, X-Spambayes-Classification: ham; 0.00 Received: from japan.t-online.private (japan.t-online.co.hu [195.228.243.99]) by people.fsn.hu (Postfix) with ESMTPSA id D42E6B79AA6; Fri, 20 Jan 2012 07:52:47 +0100 (CET) Message-ID: <4F190F3F.7050302@fsn.hu> Date: Fri, 20 Jan 2012 07:52:47 +0100 From: Attila Nagy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.23) Gecko/20090817 Thunderbird/2.0.0.23 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: freebsd-rc@frebsd.org, freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: Adding setfib support to rc.d/routing X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 07:11:07 -0000 Hi, Having multiple routing tables is a very nice and (was a) long awaited capability in FreeBSD. Having it since years is even more cool, because we can assume it's stable now. But not having infrastructure support for it sucks, this makes people hacking with rc.local or various scripts in various places. There is a(t least one) PR about it: conf/145440, which proposes a standard method for setting up different FIBs in a seems to be logical way, which is compatible with the current single routing table method of static_routes. Are there any objections about this PR? Is there something we can do to get it committed? Thanks, From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 07:15:38 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3CF5D106566C for ; Fri, 20 Jan 2012 07:15:38 +0000 (UTC) (envelope-from kes-kes@yandex.ru) Received: from forward12.mail.yandex.net (forward12.mail.yandex.net [IPv6:2a02:6b8:0:801::2]) by mx1.freebsd.org (Postfix) with ESMTP id AAFE18FC0C for ; Fri, 20 Jan 2012 07:15:37 +0000 (UTC) Received: from smtp11.mail.yandex.net (smtp11.mail.yandex.net [95.108.130.67]) by forward12.mail.yandex.net (Yandex) with ESMTP id EFA9AC224DF; Fri, 20 Jan 2012 11:15:35 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1327043736; bh=jQDq9BnkwJPcb4GSn6Zmp/DbS3PbrMjo2aQvQMKanRw=; h=Date:From:Reply-To:Message-ID:To:CC:Subject:In-Reply-To: References:MIME-Version:Content-Type:Content-Transfer-Encoding; b=thwfBYNLbWq2SH0JiiwsUFAgD7EyfUvIv5YHZr3jNstwAj97ZEJ9xKsNKgtb14Dbi JN0aR8nAHtr55TQIp58kMXkDR0TjTBC7hr4Fu0wH15O/PsNGVUH3Gd8QvRPSh9JE1h SujczugW7Viy2aHNvxyVQquZ35L5OvfA+vq58JNw= Received: from smtp11.mail.yandex.net (localhost [127.0.0.1]) by smtp11.mail.yandex.net (Yandex) with ESMTP id BFAC57E0510; Fri, 20 Jan 2012 11:15:35 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1327043735; bh=jQDq9BnkwJPcb4GSn6Zmp/DbS3PbrMjo2aQvQMKanRw=; h=Date:From:Reply-To:Message-ID:To:CC:Subject:In-Reply-To: References:MIME-Version:Content-Type:Content-Transfer-Encoding; b=vk6uhNSg5dh2nccYjyxmrlbGaFDeWv1xr4NMY0o+gq0EWg/YIktx3OdxobuOcLQ7y rk+0VpB11Zvj+a6Xb1rB36tbJVJEWBXPg5qpuAkQ+iN2FcDIigfdYP/4gNpQPCjcIj 82MO0TvofEBqA3iqT25W37js3o29BCFi4l+PZLmU= Received: from unknown (unknown [176.8.25.138]) by smtp11.mail.yandex.net (nwsmtp/Yandex) with ESMTP id FZP88Sax-FZPiEoi4; Fri, 20 Jan 2012 11:15:35 +0400 X-Yandex-Spam: 1 Date: Fri, 20 Jan 2012 09:15:33 +0200 From: =?utf-8?B?0JrQvtC90YzQutC+0LIg0JXQstCz0LXQvdC40Lk=?= X-Mailer: The Bat! (v4.0.24) Professional Organization: =?utf-8?B?0KfQnyDQmtC+0L3RjNC60L7QsiwgRnJlZUxpbmU=?= X-Priority: 3 (Normal) Message-ID: <1667449136.20120120091533@yandex.ru> To: Attila Nagy In-Reply-To: <4F190F3F.7050302@fsn.hu> References: <4F190F3F.7050302@fsn.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=windows-1251 Content-Transfer-Encoding: 8bit Cc: freebsd-net@freebsd.org, freebsd-rc@frebsd.org Subject: Re: Adding setfib support to rc.d/routing X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: =?utf-8?B?0JrQvtC90YzQutC+0LIg0JXQstCz0LXQvdC40Lk=?= List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 07:15:38 -0000 Çäđŕâńňâóéňĺ, Attila. Âű ďčńŕëč 20 ˙íâŕđ˙ 2012 ă., 8:52:47: AN> Hi, AN> Having multiple routing tables is a very nice and (was a) long awaited AN> capability in FreeBSD. Having it since years is even more cool, because AN> we can assume it's stable now. AN> But not having infrastructure support for it sucks, this makes people AN> hacking with rc.local or various scripts in various places. AN> There is a(t least one) PR about it: conf/145440, which proposes a AN> standard method for setting up different FIBs in a seems to be logical AN> way, which is compatible with the current single routing table method of AN> static_routes. AN> Are there any objections about this PR? Is there something we can do to AN> get it committed? I have a patch http://kes.net.ua/softdev/fib_patch.html AN> Thanks, AN> _______________________________________________ AN> freebsd-net@freebsd.org mailing list AN> http://lists.freebsd.org/mailman/listinfo/freebsd-net AN> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" -- Ń óâŕćĺíčĺě, Ęîíüęîâ mailto:kes-kes@yandex.ru From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 07:34:05 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4207A1065670 for ; Fri, 20 Jan 2012 07:34:05 +0000 (UTC) (envelope-from bra@fsn.hu) Received: from people.fsn.hu (people.fsn.hu [195.228.252.137]) by mx1.freebsd.org (Postfix) with ESMTP id E673E8FC0A for ; Fri, 20 Jan 2012 07:34:04 +0000 (UTC) Received: by people.fsn.hu (Postfix, from userid 1001) id A1F29BA8984; Fri, 20 Jan 2012 08:34:03 +0100 (CET) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.2 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MF-ACE0E1EA [pR: 16.9647] X-CRM114-CacheID: sfid-20120120_08340_AD987885 X-CRM114-Status: Good ( pR: 16.9647 ) X-DSPAM-Result: Whitelisted X-DSPAM-Processed: Fri Jan 20 08:34:03 2012 X-DSPAM-Confidence: 0.7631 X-DSPAM-Probability: 0.0000 X-DSPAM-Signature: 4f1918eb294972342189105 X-DSPAM-Factors: 27, From*Attila Nagy , 0.00010, FreeBSD, 0.00053, >+I, 0.00082, to+>, 0.00151, a+>, 0.00155, wrote+>, 0.00163, of+>, 0.00209, >+>, 0.00260, >+>, 0.00260, Hi+>, 0.00275, wrote, 0.00473, Is+there, 0.00574, >+That, 0.00603, References*fsn.hu>, 0.00669, there+any, 0.00708, rc, 0.00752, a+patch, 0.00752, static, 0.00771, Date*2012+08, 0.99000, not+having, 0.01000, sucks, 0.01000, hacking, 0.01000, a+PR, 0.01000, way+which, 0.99000, 08+15, 0.01000, Date*02+0100, 0.99000, X-Spambayes-Classification: ham; 0.00 Received: from japan.t-online.private (japan.t-online.co.hu [195.228.243.99]) by people.fsn.hu (Postfix) with ESMTPSA id D5B3FBA8962; Fri, 20 Jan 2012 08:34:02 +0100 (CET) Message-ID: <4F1918EA.7000803@fsn.hu> Date: Fri, 20 Jan 2012 08:34:02 +0100 From: Attila Nagy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.23) Gecko/20090817 Thunderbird/2.0.0.23 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: =?windows-1251?Q?=CA=EE=ED=FC=EA=EE=E2_=C5=E2=E3=E5=ED=E8=E9?= References: <4F190F3F.7050302@fsn.hu> <1667449136.20120120091533@yandex.ru> In-Reply-To: <1667449136.20120120091533@yandex.ru> Content-Type: text/plain; charset=windows-1251; format=flowed Content-Transfer-Encoding: 8bit Cc: freebsd-net@freebsd.org, freebsd-rc@frebsd.org Subject: Re: Adding setfib support to rc.d/routing X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 07:34:05 -0000 Çäđŕâńňâóéňĺ On 01/20/12 08:15, Ęîíüęîâ Ĺâăĺíčé wrote: > Çäđŕâńňâóéňĺ, Attila. > > Âű ďčńŕëč 20 ˙íâŕđ˙ 2012 ă., 8:52:47: > > AN> Hi, > > AN> Having multiple routing tables is a very nice and (was a) long awaited > AN> capability in FreeBSD. Having it since years is even more cool, because > AN> we can assume it's stable now. > AN> But not having infrastructure support for it sucks, this makes people > AN> hacking with rc.local or various scripts in various places. > > AN> There is a(t least one) PR about it: conf/145440, which proposes a > AN> standard method for setting up different FIBs in a seems to be logical > AN> way, which is compatible with the current single routing table method of > AN> static_routes. > > AN> Are there any objections about this PR? Is there something we can do to > AN> get it committed? > > I have a patch > http://kes.net.ua/softdev/fib_patch.html That tries to solve a different (the next one if you like) problem, and there is(are?) a PR for that too, with a similar approach. The above PR is about creating static routes for different FIBs, which is the first step. From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 08:32:25 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AFF47106566B for ; Fri, 20 Jan 2012 08:32:25 +0000 (UTC) (envelope-from ndenev@gmail.com) Received: from mail-ey0-f182.google.com (mail-ey0-f182.google.com [209.85.215.182]) by mx1.freebsd.org (Postfix) with ESMTP id 3B3028FC08 for ; Fri, 20 Jan 2012 08:32:24 +0000 (UTC) Received: by eaai10 with SMTP id i10so107352eaa.13 for ; Fri, 20 Jan 2012 00:32:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=subject:mime-version:content-type:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to:x-mailer; bh=v22Z1j1ke29OjaWmf7jzgOAjaRvEJfdQZE6koG4GzDA=; b=dnf8XqcCET9A7UdtPcxvR7tyb4hUAGPBTHIbT5gadbdAfm1QKnmfQF2S65wrBp9AJO mtIeveUCJZY5pMz6eYBfzwqrpVtCsub1oeSPLNOpdmIUAkqzUAKU0DP0rXMd9z1CDn0Y ul1rzdvk/+DdA/+QRxBWzPtseQp5Za0uZizBw= Received: by 10.213.8.4 with SMTP id f4mr7322701ebf.23.1327048344030; Fri, 20 Jan 2012 00:32:24 -0800 (PST) Received: from ndenevsa.sf.moneybookers.net (g1.moneybookers.com. [217.18.249.148]) by mx.google.com with ESMTPS id b49sm8609242eec.9.2012.01.20.00.32.21 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 20 Jan 2012 00:32:22 -0800 (PST) Mime-Version: 1.0 (Apple Message framework v1251.1) Content-Type: text/plain; charset=windows-1252 From: Nikolay Denev In-Reply-To: <3008402354236887854@unknownmsgid> Date: Fri, 20 Jan 2012 10:32:23 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <7D135FA9-6503-4263-AE55-5C80F94CDF5A@gmail.com> References: <4F131A7D.4020006@zonov.org> <733BE6AF-33E0-4C16-A222-B5F5D0519194@gmail.com> <12379405.15603.1326656127893.JavaMail.mobile-sync@vbzh28> <3008402354236887854@unknownmsgid> To: Andrey Zonov X-Mailer: Apple Mail (2.1251.1) Cc: "freebsd-net@freebsd.org" Subject: Re: ICMP attacks against TCP and PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 08:32:25 -0000 On Jan 15, 2012, at 9:52 PM, Nikolay Denev wrote: > On 15.01.2012, at 21:35, Andrey Zonov wrote: >=20 >> This helped me: >> /boot/loader.conf >> net.inet.tcp.hostcache.hashsizee536 >> net.inet.tcp.hostcache.cachelimit=1966080 >>=20 >> Actually, this is a workaround. As I remember, real problem is in >> tcp_ctlinput(), it could not update MTU for destination IP if = hostcache >> allocation fails. tcp_hc_updatemtu() should returns NULL if >> tcp_hc_insert() returns NULL and tcp_ctlinput() should check this = case >> and sets updated MTU for this particular connection if >> tcp_hc_updatemtu() fails. Otherwise we've got infinite loop in MTU >> discovery. >>=20 >>=20 >> On 15.01.2012 22:59, Nikolay Denev wrote: >>>=20 >>> % uptime >>> 7:57PM up 608 days, 4:06, 1 user, load averages: 0.30, 0.21, 0.17 >>>=20 >>> % vmstat -z|grep hostcache >>> hostcache: 136, 15372, 15136, 236, = 44946965, 10972760 >>>=20 >>>=20 >>> Hmm=85 probably I should increase this=85. >>>=20 >>=20 >> -- >> Andrey Zonov >=20 > Thanks, I will test this asap! >=20 > Regards, > Nikolay I've upgraded from 7.3-STABLE to 8.2-STABLE and bumped significantly the = hostcache tunables. So far so good, I'll report back if I see similar traffic spikes. From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 09:58:40 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3E6FD106566B; Fri, 20 Jan 2012 09:58:40 +0000 (UTC) (envelope-from dk@neveragain.de) Received: from mail.neveragain.de (mail.neveragain.de [IPv6:2001:aa8:fffc::25]) by mx1.freebsd.org (Postfix) with ESMTP id 038098FC0A; Fri, 20 Jan 2012 09:58:40 +0000 (UTC) Received: from dottie.dus.openit.net (dottie.dus.openit.net [IPv6:2001:aa8:fff3::fffd]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mail.neveragain.de (Postfix) with ESMTPSA id F29711701F; Fri, 20 Jan 2012 10:58:38 +0100 (CET) Mime-Version: 1.0 (Apple Message framework v1251.1) Content-Type: text/plain; charset=us-ascii From: =?iso-8859-1?Q?Dennis_K=F6gel?= In-Reply-To: <20120117.044533.1784742896398431105.hrs@allbsd.org> Date: Fri, 20 Jan 2012 10:58:38 +0100 Content-Transfer-Encoding: 7bit Message-Id: <9BBB9AB2-4F60-4DCB-8D25-FDEC83F62FF3@neveragain.de> References: <20120110102405.GA82356@neveragain.de> <20120117.044533.1784742896398431105.hrs@allbsd.org> To: Hiroki Sato X-Mailer: Apple Mail (2.1251.1) Cc: freebsd-net@FreeBSD.org Subject: Re: Unnecessary sleep in network.subr: ipv6_up() X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 09:58:40 -0000 Am 16.01.2012 um 20:45 schrieb Hiroki Sato: > Can you try the attached patch and let me know if it works fine on > your system? It does indeed. Thank you! - D. From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 13:32:14 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A421F1065670 for ; Fri, 20 Jan 2012 13:32:14 +0000 (UTC) (envelope-from cosmic17@yandex.ru) Received: from forward18.mail.yandex.net (forward18.mail.yandex.net [IPv6:2a02:6b8:0:1402::3]) by mx1.freebsd.org (Postfix) with ESMTP id EC83C8FC17 for ; Fri, 20 Jan 2012 13:32:12 +0000 (UTC) Received: from web3.yandex.ru (web3.yandex.ru [95.108.252.103]) by forward18.mail.yandex.net (Yandex) with ESMTP id 0C0D517827BA for ; Fri, 20 Jan 2012 17:32:11 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1327066331; bh=6kO7km5Hw1L9bxQzYjuy3sWMLEFfT3sDEDhdNMg5LBY=; h=From:To:Subject:MIME-Version:Message-Id:Date: Content-Transfer-Encoding:Content-Type; b=tGQ4U9NyQlw3BdLmjsC81wHl/Q37Eh4aCmlnCv8jufq/3HsTOqx1WWiMsYx8uFdFT v4pjQpftkXuKefJ75d/YYMWuggk0ODICJ5oOJLrrEyFxWYUPl2uThVp5uYuEdlsa2w 0UBqxaX2t3TDu/RigqSnbVy67eF11PSmhviEaXco= Received: from localhost (localhost.localdomain [127.0.0.1]) by web3.yandex.ru (Yandex) with ESMTP id E36D2208802C for ; Fri, 20 Jan 2012 17:32:10 +0400 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1327066330; bh=6kO7km5Hw1L9bxQzYjuy3sWMLEFfT3sDEDhdNMg5LBY=; h=From:To:Subject:MIME-Version:Message-Id:Date: Content-Transfer-Encoding:Content-Type; b=rJyWl/DFUlKJlQOl4HTDhJY5z8RnB1AmAg8pVxKVnuoLJRnfNkYnrQOLxEAYe9wx0 Q2diujWeBIY3/w12E7OmF4hLKDAQQPsHF+64VspI5fDuSuFLs6JCizN5V1k5vQzp7i Bj5jUd3J2SyTElVst0SIq9O9BpUk8erVJOW+5bgY= X-Yandex-Spam: 1 Received: from [79.174.46.80] ([79.174.46.80]) by web3.yandex.ru with HTTP; Fri, 20 Jan 2012 17:32:10 +0400 From: Dmukha Nikolay Envelope-From: cosmic17@yandex.ru To: freebsd-net@freebsd.org MIME-Version: 1.0 Message-Id: <220871327066330@web3.yandex.ru> Date: Fri, 20 Jan 2012 17:32:10 +0400 X-Mailer: Yamail [ http://yandex.ru ] 5.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain Subject: MSTP on FreeBSD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 13:32:14 -0000 Hello. Please, help me to setup this sheme: ******************************************************* comp1 comp2 | | | | dgs3627g(24)-----------(12)dgs3612g |(21) (9)| |______freebsd bridge_______| ******************************************************* Devices are: Dlink DGS3627G (FW 2.84-B25), Dlink DGS3612G (FW 2.84-B25), FreeBSD (8.0 stable 201105). The main target is to reserve the FreeBsd bridge. The priority route for traffic from comp 1 to comp 2 is freebsd. When the server (freebsd bridge) is down, traffic should go through the direct link between switches. I want to reserve 3 freebsd bridges. So it`s necessary to use MSTP technology. For example I try to setup MSTP for one server. In my opinion the logic of this sheme is: ******************************************************* packet from comp1-->3627-->freebsd bridge-->3612-->target (comp2) ******************************************************* I think that the Root Bridge for 3627 is freebs bridge. If freebsd bridge is down, 3612 will be Root. So I should to designate the next priority: ******************************************************* 3627 - lowest FreeBSD bridge - highest 3612 - something middle bentween FreeBSD bridge and 3627 ******************************************************* Let`s start to setup: ******************************************************* 3627 (00-22-B0-26-C1-00): config vlan default delete 1-27 create vlan bridge1 tag 101 config vlan bridge1 add unt 21-24 config stp version mstp config stp mst_config_id name bridge1 revision_level 1 config stp priority 8192 instance_id 0 create stp instance_id 2 config stp instance_id 2 add_vlan 101 config stp priority 8192 instance_id 2 enable stp 3612 (00-1E-58-D9-13-00): config vlan default delete 1-12 create vlan bridge1 tag 101 config vlan bridge1 add unt 9-12 config stp version mstp config stp mst_config_id name bridge1 revision_level 1 config stp priority 4096 instance_id 0 create stp instance_id 2 config stp instance_id 2 add_vlan 101 config stp priority 4096 instance_id 2 enable stp FreeBSD bridge: ifconfig bridge0 stp em0 stp em1 ifconfig bridge0 priority 0 ifconfig bridge0 fwddelay 4 ifconfig bridge0 maxage 6 ******************************************************* Tests: 1. There is no direct link between switches: ******************************************************* 3627: STP Instance Settings --------------------------- Instance Type : CIST Instance Status : Enabled Instance Priority : 8192 (Bridge Priority : 8192 , SYS ID Ext : 0 ) STP Instance Operational Status -------------------------------- Designated Root Bridge : 0 /00-15-17-8E-E7-EE External Root Cost : 20000 Regional Root Bridge : 8192 /00-22-B0-26-C1-00 Internal Root Cost : 0 Designated Bridge : 0 /00-15-17-8E-E7-EE Root Port : 21 Max Age : 6 Forward Delay : 4 Last Topology Change : 145 Topology Changes Count : 27 STP Instance Settings --------------------------- Instance Type : MSTI(2) Instance Status : Enabled Instance Priority : 8194 (Bridge Priority : 8192 , SYS ID Ext : 2 ) STP Instance Operational Status -------------------------------- Regional Root Bridge : 8194 /00-22-B0-26-C1-00 Internal Root Cost : 0 Designated Bridge : 8194 /00-22-B0-26-C1-00 Root Port : None Remaining Hops : 20 Last Topology Change : 101 Topology Changes Count : 27 Command: show stp ports 21 MSTP Port Information ---------------------- Port Index : 21 , Hello Time: 2 /2 , Port STP : Enabled , LBD : No External PathCost : Auto/20000 , Edge Port : False/No , P2P : Auto /Yes Port RestrictedRole : False, Port RestrictedTCN : False Port Forward BPDU : Enabled MSTI Designated Bridge Internal PathCost Prio Status Role ----- ------------------ ----------------- ---- ---------- ---------- 0 0000/0015178EE7EE 20000 128 Forwarding Root 2 2002/0022B026C100 20000 128 Forwarding Master ******************************************************* I can see the traffic with tcpdump on FreeBSD bridge. 2. There is direct link between switches: ******************************************************* 3627: STP Instance Settings --------------------------- Instance Type : CIST Instance Status : Enabled Instance Priority : 8192 (Bridge Priority : 8192 , SYS ID Ext : 0 ) STP Instance Operational Status -------------------------------- Designated Root Bridge : 0 /00-15-17-8E-E7-EE External Root Cost : 20000 Regional Root Bridge : 4096 /00-1E-58-D9-13-00 Internal Root Cost : 20000 Designated Bridge : 4096 /00-1E-58-D9-13-00 Root Port : 24 Max Age : 6 Forward Delay : 4 Last Topology Change : 387 Topology Changes Count : 26 STP Instance Settings --------------------------- Instance Type : MSTI(2) Instance Status : Enabled Instance Priority : 8194 (Bridge Priority : 8192 , SYS ID Ext : 2 ) STP Instance Operational Status -------------------------------- Regional Root Bridge : 4098 /00-1E-58-D9-13-00 Internal Root Cost : 20000 Designated Bridge : 4098 /00-1E-58-D9-13-00 Root Port : 24 Remaining Hops : 19 Last Topology Change : 473 Topology Changes Count : 26 Command: show stp ports 24 MSTP Port Information ---------------------- Port Index : 24 , Hello Time: 2 /2 , Port STP : Enabled , LBD : No External PathCost : Auto/20000 , Edge Port : False/No , P2P : Auto /Yes Port RestrictedRole : False, Port RestrictedTCN : False Port Forward BPDU : Enabled MSTI Designated Bridge Internal PathCost Prio Status Role ----- ------------------ ----------------- ---- ---------- ---------- 0 1000/001E58D91300 20000 128 Forwarding Root 2 1002/001E58D91300 20000 128 Forwarding Root Command: show stp ports 21 MSTP Port Information ---------------------- Port Index : 21 , Hello Time: 2 /2 , Port STP : Enabled , LBD : No External PathCost : Auto/20000 , Edge Port : False/No , P2P : Auto /Yes Port RestrictedRole : False, Port RestrictedTCN : False Port Forward BPDU : Enabled MSTI Designated Bridge Internal PathCost Prio Status Role ----- ------------------ ----------------- ---- ---------- ---------- 0 0000/0015178EE7EE 20000 128 Discarding Alternate 2 2002/0022B026C100 20000 128 Discarding Alternate 3612: STP Instance Settings --------------------------- Instance Type : CIST Instance Status : Enabled Instance Priority : 4096 (Bridge Priority : 4096 , SYS ID Ext : 0 ) STP Instance Operational Status -------------------------------- Designated Root Bridge : 0 /00-15-17-8E-E7-EE External Root Cost : 20000 Regional Root Bridge : 4096 /00-1E-58-D9-13-00 Internal Root Cost : 0 Designated Bridge : 0 /00-15-17-8E-E7-EE Root Port : 9 Max Age : 6 Forward Delay : 4 Last Topology Change : 510 Topology Changes Count : 11 STP Instance Settings --------------------------- Instance Type : MSTI(2) Instance Status : Enabled Instance Priority : 4098 (Bridge Priority : 4096 , SYS ID Ext : 2 ) STP Instance Operational Status -------------------------------- Regional Root Bridge : 4098 /00-1E-58-D9-13-00 Internal Root Cost : 0 Designated Bridge : 4098 /00-1E-58-D9-13-00 Root Port : None Remaining Hops : 20 Last Topology Change : 532 Topology Changes Count : 11 Command: show stp ports 9 MSTP Port Information ---------------------- Port Index : 9 , Hello Time: 2 /2 , Port STP : Enabled , LBD : No External PathCost : Auto/20000 , Edge Port : False/No , P2P : Auto /Yes Port RestrictedRole : False, Port RestrictedTCN : False Port Forward BPDU : Enabled MSTI Designated Bridge Internal PathCost Prio Status Role ----- ------------------ ----------------- ---- ---------- ---------- 0 0000/0015178EE7EE 20000 128 Forwarding Root 2 1002/001E58D91300 20000 128 Forwarding Master Command: show stp ports 12 MSTP Port Information ---------------------- Port Index : 12 , Hello Time: 2 /2 , Port STP : Enabled , LBD : No External PathCost : Auto/20000 , Edge Port : False/No , P2P : Auto /Yes Port RestrictedRole : False, Port RestrictedTCN : False Port Forward BPDU : Enabled MSTI Designated Bridge Internal PathCost Prio Status Role ----- ------------------ ----------------- ---- ---------- ---------- 0 1000/001E58D91300 20000 128 Forwarding Designated 2 1002/001E58D91300 20000 128 Forwarding Designated ******************************************************* And the priority road for traffic - direct link... I think the mistake is in FreeBSD, because without freebsd server (two direct links) it is OK... Can you help me to correct setup freebsd? Thanks. From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 13:34:31 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77250106564A for ; Fri, 20 Jan 2012 13:34:31 +0000 (UTC) (envelope-from sem@semmy.ru) Received: from sunner.semmy.ru (sunner.semmy.ru [IPv6:2a00:14d0:0:20::3]) by mx1.freebsd.org (Postfix) with ESMTP id BDA108FC1B for ; Fri, 20 Jan 2012 13:34:30 +0000 (UTC) Received: from dhcp170-160-red.yandex.net ([95.108.170.160]) by sunner.semmy.ru with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.77 (FreeBSD)) (envelope-from ) id 1RoEbH-000LVQ-5u for freebsd-net@freebsd.org; Fri, 20 Jan 2012 17:33:51 +0400 Message-ID: <4F196D64.6020508@semmy.ru> Date: Fri, 20 Jan 2012 17:34:28 +0400 From: Sergey Matveychuk User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0) Gecko/20111222 Thunderbird/9.0.1 MIME-Version: 1.0 To: freebsd-net@freebsd.org References: <4F190F3F.7050302@fsn.hu> In-Reply-To: <4F190F3F.7050302@fsn.hu> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: Adding setfib support to rc.d/routing X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 13:34:31 -0000 20.01.2012 10:52, Attila Nagy wrote: > Hi, > > Having multiple routing tables is a very nice and (was a) long awaited > capability in FreeBSD. Having it since years is even more cool, because > we can assume it's stable now. > But not having infrastructure support for it sucks, this makes people > hacking with rc.local or various scripts in various places. > > There is a(t least one) PR about it: conf/145440, which proposes a > standard method for setting up different FIBs in a seems to be logical > way, which is compatible with the current single routing table method of > static_routes. > > Are there any objections about this PR? Is there something we can do to > get it committed? > JFYI conf/132476 From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 20:30:29 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 61DFE1065672; Fri, 20 Jan 2012 20:30:29 +0000 (UTC) (envelope-from ray@freebsd.org) Received: from smtp.dlink.ua (smtp.dlink.ua [193.138.187.146]) by mx1.freebsd.org (Postfix) with ESMTP id B7ADF8FC1E; Fri, 20 Jan 2012 20:30:28 +0000 (UTC) Received: from rnote.ddteam.net (55-40-133-95.pool.ukrtel.net [95.133.40.55]) (Authenticated sender: ray) by smtp.dlink.ua (Postfix) with ESMTPSA id 4CA9AC493A; Fri, 20 Jan 2012 22:13:29 +0200 (EET) Date: Fri, 20 Jan 2012 22:13:19 +0200 From: Aleksandr Rybalko To: freebsd-arch@FreeBSD.org, freebsd-net@FreeBSD.org Message-Id: <20120120221319.ca8b631f.ray@freebsd.org> Organization: FreeBSD.ORG X-Mailer: Sylpheed 3.1.2 (GTK+ 2.24.5; amd64-portbld-freebsd9.0) X-Operating-System: FreeBSD Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: Subject: Ethernet Switch Framework X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 20:30:29 -0000 Hi, Sorry for cross posting. I just thought this might interesting to review for subscribers on both MLs. I glad to introduce working version of Ethernet Switch Framework. of course, here is so many things to do, but it already work and can help us in some situations for embedded devices. here is the patch: http://my.ddteam.net/files/2012-01-20_switch_framework.patch It include sys/mips/conf/AR7240, that together with hints file is good example for typical AR7240 setup. Since it still don't have any documentation, I will try to explain it here. The framework contain 3 basic parts: 1. core module, which handle ioctl calls and interact with driver. 2. Various bus glue (now it is obio(mem), mii(MDIO) and IIC in near future) 3. drivers. Atheros AR8x16, Broadcom BCM53xx, Ralink RT305xF, Realtek RTL8305/09 4. FloatPHY, pseudo driver which find master switchX device and ask his PHY reg's. 5. switchctl utility. Utility. Currently can do switchctl /dev/switch0 (get|set) (reg|port|vlan) [flags] get/set port: get or set port flags: "IngressCheck" - put port into VLAN mode, drop packets which have 802.1q tag with value != PVID "Q-in-Q" - enable double tag, add second tag to already tagged packets. "LAN" and "WAN" - flags, for switches which have special function for LAN-WAN processing. "Tagged" and "Untagged" - mark port Tagged/Untagged, used if switch using Global Tag flag (one flag for all VLANs) "pvid" - set Port VLAN ID Example: switchctl /dev/switch0 set port 2 pvid 2 flags IngressCheck LAN Tagged get/set vlan V: add N (tag|untag|forbid) - add port N to VLAN member ports as (tag| untag| forbid) del N - delete port N from VLAN member ports vid N - assign VLAN ID to internal index V Example: switchctl /dev/switch0 set vlan 2 vid 12 switchctl /dev/switch0 set vlan 2 add 2 u switchctl /dev/switch0 set vlan 2 del 1 get/set reg: Generic access to registers. Have 2 address modifiers: 0x00000000(no modifiers) - access to parent space (parent MDIO bus, if switchX attaches to miibusX) 0x40000000 - access to switch MDIO bus 0x80000000 - access to switch registers. Example: # switchctl /dev/switch0 get reg 0x80000008 Reg 0x80000008 Value = 0x012603e2 # switchctl /dev/switch0 get reg 0x00000008 Reg 0x00000008 Value = 0x0000ffff # switchctl /dev/switch0 get reg 0x40000001 Reg 0x40000001 Value = 0x00007949 # switchctl /dev/switch0 set reg 0x80000008 0x012603e2 Reg 0x80000008 Value = 0x012603e2 (Old value = 0x012603e2) FloatPHY pseudo driver which attach to miibus like normal PHY, but do find master switchX device and ask his PHY reg's. Main problem with that driver - is usage of newbus calls between independent device (not a parent <-> child), since floatphyX query set/get methods of switchX. Use hints: "master" - to set master name. "master_unit" - master unit. "master_phys" - bitmap of PHY numbers on which get link status/speed. "flags" - see driver (dev/switch/floatphy.c). "speed" - initial link speed value, used when no access to master. I will describe as example 4 situation that current framework is cover: 1. Ralink RT305X SoC, internal switch, one NIC with two paths. 2. Atheros AR7240 SoC, two NIC, but MDIO routed only from second 3. Cavium Octeon CN5010, one NIC with three paths + BCM53115 switch + some Broadcom PHY 1. Ralink RT305X - is simple one Attached by obio0 if driver present in kernel. VLAN features: it have so called global untagged flag, so port can be member of any VLAN but may be tagged or untagged in all VLAN in same time. How to enable: just add following into kernel config file. ------------------------------------------------ device switch device switch_rt305x ------------------------------------------------ 2. Atheros AR7240 - very interesting. have AR8216 internal switch and two arge NICs. arge0 MII bus connected to PHY4 which configured as separate PHY(not attached to switch core). But PHY4 reg's can be accessible only via switch MDIO bus access. arge1 MII bus connected to switch MII. But MDIO bus wired only on arge0, so if arge0 want to know speed and link status, it must ask switch connected to miibus attached to arge1. [1] Page 3 VLAN features: Like RT395x use global untagged like flag. How to enable (example config for AR7240 in patch) Config: ------------------------------------------------ device mii device switch device switch_ar8x16 ------------------------------------------------ hints: ------------------------------------------------ # No probe at all # First MDIO connected to switch which not have real PHY regs hint.miibus.0.phymask="0x00000000" # Second MDIO not wired at all hint.miibus.1.phymask="0x00000000" # Connect pseudo PHY driver to miibus0 hint.floatphy.0.at="miibus0" hint.floatphy.0.phyno=0 # floatphy0 will ask switch0 hint.floatphy.0.master="switch" hint.floatphy.0.master_unit=0 # and get link status from PHYs masked by 0x00000010 hint.floatphy.0.master_phys=0x00000010 # Sense PHY4 hint.floatphy.0.flags=0x00000000 # Default link speed 100 (if no access to master) hint.floatphy.0.speed=100 # Switch attached to MDIO bus on arge0 hint.switch.0.at="miibus0" hint.switch.0.phyno=1 # AR8x16 Magic register which can configure PHY4 as a standalone PHY hint.ar8x16_switch.0.mii_mode=0x012603e2 hint.floatphy.1.at="miibus1" hint.floatphy.1.phyno=0 hint.floatphy.1.master="switch" hint.floatphy.1.master_unit=0 # check link on PHY0-PHY3 (link on any rise link on arge1) hint.floatphy.1.master_phys=0x0000000f # Link Sensing PHY0-PHY3 hint.floatphy.1.flags=0x00000004 # "Link on any PHYs" | "Static link speed" hint.floatphy.1.speed=1000 ------------------------------------------------ 3. Cavium Octeon CN5010, one NIC with three paths + BCM53115 switch + some Broadcom PHY. Since here is required a lot of magic to attach anything that Cavium was not expect as "can be attached" (i.e. Cavium SDK limitation), I made patch which allow to attach one PHY driver per NIC path (per octe0 iface). VLAN features: it seems have most clear VLAN implementation, except some things like remapped some regs which have port bit maps. (seems forget to think about bigger port count when design small switches) How to enable: Config: ------------------------------------------------ device brgphy device switch device switch_bcm5325 ------------------------------------------------ Hints: ------------------------------------------------ hint.miibus.0.phymask="0x00000000" hint.miibus.1.phymask="0x00000000" hint.miibus.3.phymask="0x00000100" # brgphy will attach here hint.floatphy.0.at="miibus0" hint.floatphy.0.phyno=0 hint.floatphy.0.master="switch" hint.floatphy.0.master_unit=0 # Check link on any ports hint.floatphy.0.master_phys=0x0000001f # Sense PHY0 hint.floatphy.0.flags=0x00000000 hint.floatphy.0.speed=1000 hint.switch.0.at="miibus1" hint.switch.0.phyno=30 ------------------------------------------------ Huh, hope that is enough for first release of manual :) Will wait for any comments and suggestions! We're committing this in 5 days unless anyone objects in any meaningful way. 1. http://my.ddteam.net/files/Switch_Framework.pdf WBW -- Aleksandr Rybalko From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 22:36:03 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 23F77106564A for ; Fri, 20 Jan 2012 22:36:03 +0000 (UTC) (envelope-from stb@lassitu.de) Received: from gilb.zs64.net (gilb.zs64.net [IPv6:2001:470:1f0b:105e::1ea]) by mx1.freebsd.org (Postfix) with ESMTP id 9DD7C8FC16 for ; Fri, 20 Jan 2012 22:35:58 +0000 (UTC) Received: by gilb.zs64.net (Postfix, from stb@lassitu.de) id 7868F11D16D for ; Fri, 20 Jan 2012 22:35:56 +0000 (UTC) From: Stefan Bethke Content-Type: multipart/mixed; boundary="Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4" Date: Fri, 20 Jan 2012 23:35:55 +0100 Message-Id: <76C5AEDF-39BA-4824-B8F8-BBD451200EF2@lassitu.de> To: FreeBSD Net Mime-Version: 1.0 (Apple Message framework v1251.1) X-Mailer: Apple Mail (2.1251.1) X-Mailman-Approved-At: Fri, 20 Jan 2012 22:43:34 +0000 Subject: Ethernet Switch Framework, the other one X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 22:36:03 -0000 --Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii If you have followed a number of threads on -embedded, -mips, and -arch, = you'll be aware that I've been busy attempting to come up with a switch = control interface of my own. The goal is to combine what Aleksandr has = done over the past couple of months with some of what I have come up = with. The reason I did start from scratch were some architectural concerns = that I had with Aleksandr's code. Instead of idle talk, I decided to do = a proof of concept implementation, and lo and behold, I did run into = some interesting problems. I'll reply to Aleksandr's post momentarily, = but first I wanted to get my code out for people to review, and use the = chance try and explain the problem space and why I decided to approach = it the way I did. The attached patches contain: - etherswitchcfg.patch the userland utility - miiproxy.patch a device that can act as a proxy between an ethernet = driver and miibus - etherswitch-complete: the above plus two switch drivers, a new kernel = config and related files. All that can also be obtained from = http://gitorious.org/~stb/freebsd/stb-adrianchadd-freebsd-work in the = branch work/ath. The target systems for these switch device drivers are typical WLAN = routers, which usually contain a one-chip switch controller. All of = them support port-based as well as .1q VLANs, as well as many other = interesting features. OpenWrt has a framework for configuring aspects = of these switch controllers, but the original firmware of these devices = usually does not expose the settings for the user. For my proof of concept, I've put together two drivers that know how to = configure an RTL8366RB and AR8x16 switches. The RTL8366RB is configured = through I2C. The system's ethernet interface is connected directly to a = switch port (back-to-back MAC connection via GMII). The Atheros family = of switch controllers is configured through an MDIO bus attachment; the = switch controller uses the frame format, but reassigns phy address bits = as register address bits. Both switch drivers implement the etherswitch_if.m interface, and act as = busses and automatically attach matching drivers as children. I've = written a simple cdev driver that allows the command line utility to = open a control device and submit ioctls that are translated into = etherswitch_if methods. newbus attachments look like this (arrow indicates parent attachment = with interface implemented) iicbus_if etherswitch_if ... <--- iicbus <--- rtl833rb <--- etherswitch mdio_if mdio_if etherswitch_if argemdio <--- mdio <--- arswitch <--- etherswitch All switch controller chips contain PHYs (older models have external = PHYs). These are controlled in the usual manner via MDIO. The MDIO = master is in the switch controller. Both switch drivers export the = miibus_if.m methods readreg and writereg, and attach an miibus for each = one of the switch ports that have a PHY. This allows the command line = utility to submit ifmedia ioctls to query and configure the individual = ports. I've gone through a number of iterations to make sure that the = interdependencies of the drivers are as limited as possible, and that = attachments happen automatically, without code nor hints, whereever = possible. MII Proxy In some of the systems, one system ethernet interface is connected to a = PHY inside the switch controller; the PHY acts completely independent = from the switch. However, the PHYs MDIO slave is connected not to the = ethernet controllers MDIO master, but to the switch MDIO master. This = means solving two problems: allowing a driver control both an ethernet = driver and use another MDIO bus driver to communicate with the PHY at = the same time. The miibus code unfortunately is extremely tailored to the one use case = that was present so far; I'll go into more detail about what was = stopping me from just using miibus directly in a separate post. To = leave miibus unmodified while maintaining functionality and not = reimplementing miibus or the phy drivers, I've decided to create a proxy = driver. This proxy driver solves two issues: be an appropriate parent = for miibus, and provide the capability to have a reference on a = different device (and call methods there) than the parent. A new bus = driver, mdio, provides the MDIO readreg and writereg methods separate = from the miibus driver, thus allowing automatic attachment of parent and = children. For a TL-MR3420 router, devinfo shows this device graph (filtered for = interface and switch components): nexus0 arge0 miiproxy0 miibus4 ukphy4 arge1 argemdio0 mdio0 arswitch0 miibus0 ukphy0 miibus1 ukphy1 miibus2 ukphy2 miibus3 ukphy3 etherswitch0 mdio1 mdioproxy1 mdioproxy0 arge(4) has been extended with a separate mdio host driver that has a = new mdio bus driver attached. The Atheros switch driver arswitch0 is = attached to that bus; the four switch ports with PHYs on them show up as = miibus0 to miibus3 and phy0 to phy3, respectively. arge0, which has the = MII connection (but not the MDIO connection) to PHY for in the switch = controller, has miiproxy0 attached to it, which in turn hosts miibus4 = and phy4. miiproxy0 has a hidden connection to mdioproxy1 that was = established through a hint on arge0; miiproxy0 uses mdioproxy1's parent = to issue readreg and writereg calls on behalf of miibus. Note = mdioproxy0 above which was automatically attached (but is not used). The only hint required to plug this together is hint.arge.0.mdio=3Dmdioproxy1 The simple and straightforward attachment follows the newbus design, and = allows additional drivers to be automatically attached by newbus. The = etherswitch driver provides one possible consumer of the etherswitch_if = API, but other are possible; for example, most switches allow .1d = control frames to be punted to the CPU port, so our STP code could be = used to construct a driver that implements spanning tree for a switch. Stefan --=20 Stefan Bethke Fon +49 151 14070811 --Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4 Content-Disposition: attachment; filename=etherswitchcfg.patch Content-Type: application/octet-stream; name="etherswitchcfg.patch" Content-Transfer-Encoding: 7bit diff --git a/sbin/Makefile b/sbin/Makefile index f9ba4ca..0cb421f 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -20,6 +20,7 @@ SUBDIR=adjkerntz \ dump \ dumpfs \ dumpon \ + etherswitchcfg \ ffsinfo \ fsck \ fsck_ffs \ diff --git a/sbin/etherswitchcfg/Makefile b/sbin/etherswitchcfg/Makefile new file mode 100644 index 0000000..d21c88b --- /dev/null +++ b/sbin/etherswitchcfg/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 5.4 (Berkeley) 6/5/91 +# $FreeBSD: head/sbin/comcontrol/Makefile 198236 2009-10-19 16:00:24Z ru $ + +PROG= etherswitchcfg +MAN= etherswitchcfg.8 +SRCS= etherswitchcfg.c ifmedia.c +CFLAGS+= -I${.CURDIR}/../../sys + +.include diff --git a/sbin/etherswitchcfg/etherswitchcfg.8 b/sbin/etherswitchcfg/etherswitchcfg.8 new file mode 100644 index 0000000..538950c --- /dev/null +++ b/sbin/etherswitchcfg/etherswitchcfg.8 @@ -0,0 +1,114 @@ +.\" $FreeBSD$ +.Dd December 15, 2011 +.Dt ETHERSWITCHCFG 8 +.Os +.Sh NAME +.Nm etherswitchcfg +.Nd configure a built-in Ethernet switch +.Sh SYNOPSIS +.Nm +.Op Fl "f control file" +.Ar info +.Nm +.Op Fl "f control file" +.Ar phy +.Ar phy.register[=value] +.Nm +.Op Fl "f control file" +.Ar port%d +.Ar command parameter +.Nm +.Op Fl "f control file" +.Ar reg +.Ar register[=value] +.Nm +.Op Fl "f control file" +.Ar vlangroup%d +.Ar command parameter +.Sh DESCRIPTION +The +.Nm +utility is used to configure an Ethernet switch built into the system. +.Nm +accepts a number of options: +.Bl -tag -width ".Fl f" -compact +.It Fl "f control file" +Specifies the +.Xr etherswitch 4 +control file that represents the switch to be configured. +It defaults to +.Li /dev/etherswitch0 . +.It Fl m +When reporting port information, also list available media options for +that port. +.It Fl v +Produce more verbose output. +Without this flag, lines that represent inactive or empty configuration +options are omitted. +.El +.Ss phy +The phy command provides access to the registers of the PHYs attached +to or integrated into the switch controller. +PHY registers are specified as phy.register, +where +.Ar phy +is usually the port number, and +.Ar register +is the register number. +Both can be provided as decimal, octal or hexadecimal numbers in any of the formats +understood by +.Xr strtol 4 . +To set the register value, use the form instance.register=value. +.Ss port +The port command selects one of the ports of the switch. +It supports the following commands: +.Bl -tag -width ".Ar vlangroup number" -compact +.It Ar vlangroup number +Sets the VLAN group number that is used to process incoming frames that are not tagged. +.It Ar media mediaspec +Specifies the physical media configuration to be configured for a port. +.It Ar mediaopt mediaoption +Specifies a list of media options for a port. See +.Xr ifconfig 8 +for details on +.Ar media and +.Ar mediaopt . +.El +.Ss reg +The reg command provides access to the registers of the switch controller. +.Ss vlangroup +The vlangroup command selects one of the VLAN groups for configuration. +It supports the following commands: +.Bl -tag -width ".Ar vlangroup" -compact +.It Ar vlan VID +Sets the VLAN ID (802.1q VID) for this VLAN group. +Frames transmitted on tagged member ports of this group will be tagged +with this VID. +Incoming frames carrying this tag will be forwarded according to the +configuration of this VLAN group. +.It Ar members port,... +Configures which ports are to be a member of this VLAN group. +The port numbers are given as a comma-separated list. +Each port can optionally be followed by +.Dq t +to indicate that frames on this port are tagged. +.El +.Sh FILES +.Bl -tag -width /dev/etherswitch? -compact +.It Pa /dev/etherswitch? +Control file for the ethernet switch driver. +.El +.Sh EXAMPLES +Configure VLAN group 1 with a VID of 2 and makes ports 0 and 5 members, +while excluding all other ports. +Port 5 will send and receive tagged frames, while port 0 will be untagged. +Incoming untagged frames on port 0 are assigned to vlangroup1. +.Dl # etherswitchcfg vlangroup1 vlan 2 members 0,5t port0 vlangroup 1 +.Sh SEE ALSO +.Xr etherswitch 4 +.Sh HISTORY +.Nm +first appeared in +.Fx 10.0 . +.Sh AUTHORS +.An Stefan Bethke diff --git a/sbin/etherswitchcfg/etherswitchcfg.c b/sbin/etherswitchcfg/etherswitchcfg.c new file mode 100644 index 0000000..e6129f3 --- /dev/null +++ b/sbin/etherswitchcfg/etherswitchcfg.c @@ -0,0 +1,511 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int get_media_subtype(int, const char *); +int get_media_mode(int, const char *); +int get_media_options(int, const char *); +int lookup_media_word(struct ifmedia_description *, const char *); +void print_media_word(int, int); +void print_media_word_ifconfig(int); + +/* some constants */ +#define IEEE802DOT1Q_VID_MAX 4094 +#define IFMEDIAREQ_NULISTENTRIES 256 + +enum cmdmode { + MODE_NONE = 0, + MODE_PORT, + MODE_VLANGROUP, + MODE_REGISTER, + MODE_PHYREG +}; + +struct cfg { + int fd; + int verbose; + int mediatypes; + const char *controlfile; + etherswitch_info_t info; + enum cmdmode mode; + int unit; +}; + +struct cmds { + enum cmdmode mode; + const char *name; + int args; + void (*f)(struct cfg *, char *argv[]); +}; +struct cmds cmds[]; + + +static void usage(void); + +static int +read_register(struct cfg *cfg, int r) +{ + struct etherswitch_reg er; + + er.reg = r; + if (ioctl(cfg->fd, IOETHERSWITCHGETREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETREG)"); + return (er.val); +} + +static void +write_register(struct cfg *cfg, int r, int v) +{ + struct etherswitch_reg er; + + er.reg = r; + er.val = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETREG)"); +} + +static int +read_phyregister(struct cfg *cfg, int phy, int reg) +{ + struct etherswitch_phyreg er; + + er.phy = phy; + er.reg = reg; + if (ioctl(cfg->fd, IOETHERSWITCHGETPHYREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPHYREG)"); + return (er.val); +} + +static void +write_phyregister(struct cfg *cfg, int phy, int reg, int val) +{ + struct etherswitch_phyreg er; + + er.phy = phy; + er.reg = reg; + er.val = val; + if (ioctl(cfg->fd, IOETHERSWITCHSETPHYREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPHYREG)"); +} + +static void +set_port_vlangroup(struct cfg *cfg, char *argv[]) +{ + int v; + etherswitch_port_t p; + + v = strtol(argv[1], NULL, 0); + if (v < 0 || v >= cfg->info.es_nvlangroups) + errx(EX_USAGE, "vlangroup must be between 0 and %d", cfg->info.es_nvlangroups-1); + p.es_port = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + p.es_vlangroup = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_port_media(struct cfg *cfg, char *argv[]) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int subtype; + + bzero(&p, sizeof(p)); + p.es_port = cfg->unit; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + subtype = get_media_subtype(IFM_TYPE(ifm_ulist[0]), argv[1]); + p.es_ifr.ifr_media = (p.es_ifmr.ifm_current & IFM_IMASK) | + IFM_TYPE(ifm_ulist[0]) | subtype; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_port_mediaopt(struct cfg *cfg, char *argv[]) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int options; + + bzero(&p, sizeof(p)); + p.es_port = cfg->unit; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + options = get_media_options(IFM_TYPE(ifm_ulist[0]), argv[1]); + if (options == -1) + errx(EX_USAGE, "invalid media options \"%s\"", argv[1]); + if (options & IFM_HDX) { + p.es_ifr.ifr_media &= ~IFM_FDX; + options &= ~IFM_HDX; + } + p.es_ifr.ifr_media |= options; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_vlangroup_vid(struct cfg *cfg, char *argv[]) +{ + int v; + etherswitch_vlangroup_t vg; + + v = strtol(argv[1], NULL, 0); + if (v < 0 || v >= IEEE802DOT1Q_VID_MAX) + errx(EX_USAGE, "vlan must be between 0 and %d", IEEE802DOT1Q_VID_MAX); + vg.es_vlangroup = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + vg.es_vid = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)"); +} + +static void +set_vlangroup_members(struct cfg *cfg, char *argv[]) +{ + etherswitch_vlangroup_t vg; + int member, untagged; + char *c, *d; + int v; + + member = untagged = 0; + if (strcmp(argv[1], "none") != 0) { + for (c=argv[1]; *c; c=d) { + v = strtol(c, &d, 0); + if (d == c) + break; + if (v < 0 || v >= cfg->info.es_nports) + errx(EX_USAGE, "Member port must be between 0 and %d", cfg->info.es_nports-1); + if (d[0] == ',' || d[0] == '\0' || + ((d[0] == 't' || d[0] == 'T') && (d[1] == ',' || d[1] == '\0'))) { + if (d[0] == 't' || d[0] == 'T') { + untagged &= ~ETHERSWITCH_PORTMASK(v); + d++; + } else + untagged |= ETHERSWITCH_PORTMASK(v); + member |= ETHERSWITCH_PORTMASK(v); + d++; + } else + errx(EX_USAGE, "Invalid members specification \"%s\"", d); + } + } + vg.es_vlangroup = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + vg.es_member_ports = member; + vg.es_untagged_ports = untagged; + if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)"); +} + +static int +set_register(struct cfg *cfg, char *arg) +{ + int a, v; + char *c; + + a = strtol(arg, &c, 0); + if (c==arg) + return (1); + if (*c == '=') { + v = strtol(c+1, NULL, 0); + write_register(cfg, a, v); + } + printf("\treg 0x%04x=0x%04x\n", a, read_register(cfg, a)); + return (0); +} + +static int +set_phyregister(struct cfg *cfg, char *arg) +{ + int phy, reg, val; + char *c, *d; + + phy = strtol(arg, &c, 0); + if (c==arg) + return (1); + if (*c != '.') + return (1); + d = c+1; + reg = strtol(d, &c, 0); + if (d == c) + return (1); + if (*c == '=') { + val = strtol(c+1, NULL, 0); + write_phyregister(cfg, phy, reg, val); + } + printf("\treg %d.0x%02x=0x%04x\n", phy, reg, read_phyregister(cfg, phy, reg)); + return (0); +} + +static void +print_port(struct cfg *cfg, int port) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int i; + + bzero(&p, sizeof(p)); + p.es_port = port; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + printf("port%d:\n", port); + printf("\tvlangroup: %d\n", p.es_vlangroup); + printf("\tmedia: "); + print_media_word(p.es_ifmr.ifm_current, 1); + if (p.es_ifmr.ifm_active != p.es_ifmr.ifm_current) { + putchar(' '); + putchar('('); + print_media_word(p.es_ifmr.ifm_active, 0); + putchar(')'); + } + putchar('\n'); + printf("\tstatus: %s\n", (p.es_ifmr.ifm_status & IFM_ACTIVE) != 0 ? "active" : "no carrier"); + if (cfg->mediatypes) { + printf("\tsupported media:\n"); + if (p.es_ifmr.ifm_count > IFMEDIAREQ_NULISTENTRIES) + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + for (i=0; ifd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + if (cfg->verbose == 0 && vg.es_member_ports == 0) + return; + printf("vlangroup%d:\n", vlangroup); + printf("\tvlan: %d\n", vg.es_vid); + printf("\tmembers "); + comma = 0; + if (vg.es_member_ports != 0) + for (i=0; iinfo.es_nports; i++) { + if ((vg.es_member_ports & ETHERSWITCH_PORTMASK(i)) != 0) { + if (comma) + printf(","); + printf("%d", i); + if ((vg.es_untagged_ports & ETHERSWITCH_PORTMASK(i)) == 0) + printf("t"); + comma = 1; + } + } + else + printf("none"); + printf("\n"); +} + +static void +print_info(struct cfg *cfg) +{ + const char *c; + int i; + + c = strrchr(cfg->controlfile, '/'); + if (c != NULL) + c = c + 1; + else + c = cfg->controlfile; + if (cfg->verbose) + printf("%s: %s with %d ports and %d VLAN groups\n", + c, cfg->info.es_name, cfg->info.es_nports, cfg->info.es_nvlangroups); + for (i=0; iinfo.es_nports; i++) { + print_port(cfg, i); + } + for (i=0; iinfo.es_nvlangroups; i++) { + print_vlangroup(cfg, i); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: etherswitchctl\n"); + exit(EX_USAGE); +} + +static void +newmode(struct cfg *cfg, enum cmdmode mode) +{ + if (mode == cfg->mode) + return; + switch (cfg->mode) { + case MODE_NONE: + break; + case MODE_PORT: + print_port(cfg, cfg->unit); + break; + case MODE_VLANGROUP: + print_vlangroup(cfg, cfg->unit); + break; + case MODE_REGISTER: + case MODE_PHYREG: + break; + } + cfg->mode = mode; +} + +int +main(int argc, char *argv[]) +{ + int ch; + struct cfg cfg; + int i; + + bzero(&cfg, sizeof(cfg)); + cfg.controlfile = "/dev/etherswitch0"; + while ((ch = getopt(argc, argv, "f:mv?")) != -1) + switch(ch) { + case 'f': + cfg.controlfile = optarg; + break; + case 'm': + cfg.mediatypes++; + break; + case 'v': + cfg.verbose++; + break; + case '?': + /* FALLTHROUGH */ + default: + usage(); + } + argc -= optind; + argv += optind; + cfg.fd = open(cfg.controlfile, O_RDONLY); + if (cfg.fd < 0) + err(EX_UNAVAILABLE, "Can't open control file: %s", cfg.controlfile); + if (ioctl(cfg.fd, IOETHERSWITCHGETINFO, &cfg.info) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETINFO)"); + if (argc == 0) { + print_info(&cfg); + return (0); + } + cfg.mode = MODE_NONE; + while (argc > 0) { + switch(cfg.mode) { + case MODE_NONE: + if (strcmp(argv[0], "info") == 0) { + print_info(&cfg); + } else if (sscanf(argv[0], "port%d", &cfg.unit) == 1) { + if (cfg.unit < 0 || cfg.unit >= cfg.info.es_nports) + errx(EX_USAGE, "port unit must be between 0 and %d", cfg.info.es_nports); + newmode(&cfg, MODE_PORT); + } else if (sscanf(argv[0], "vlangroup%d", &cfg.unit) == 1) { + if (cfg.unit < 0 || cfg.unit >= cfg.info.es_nvlangroups) + errx(EX_USAGE, "port unit must be between 0 and %d", cfg.info.es_nvlangroups); + newmode(&cfg, MODE_VLANGROUP); + } else if (strcmp(argv[0], "phy") == 0) { + newmode(&cfg, MODE_PHYREG); + } else if (strcmp(argv[0], "reg") == 0) { + newmode(&cfg, MODE_REGISTER); + } else { + errx(EX_USAGE, "Unknown command \"%s\"", argv[0]); + } + break; + case MODE_PORT: + case MODE_VLANGROUP: + for(i=0; cmds[i].name != NULL; i++) { + if (cfg.mode == cmds[i].mode && strcmp(argv[0], cmds[i].name) == 0 + && argc >= cmds[i].args) { + (cmds[i].f)(&cfg, argv); + argc -= cmds[i].args; + argv += cmds[i].args; + break; + } + } + if (cmds[i].name == NULL) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + case MODE_REGISTER: + if (set_register(&cfg, argv[0]) != 0) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + case MODE_PHYREG: + if (set_phyregister(&cfg, argv[0]) != 0) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + } + argc--; + argv++; + } + /* switch back to command mode to print configuration for last command */ + newmode(&cfg, MODE_NONE); + close(cfg.fd); + return (0); +} + +struct cmds cmds[] = { + { MODE_PORT, "vlangroup", 1, set_port_vlangroup }, + { MODE_PORT, "media", 1, set_port_media }, + { MODE_PORT, "mediaopt", 1, set_port_mediaopt }, + { MODE_VLANGROUP, "vlan", 1, set_vlangroup_vid }, + { MODE_VLANGROUP, "members", 1, set_vlangroup_members }, + { 0, NULL, 0, NULL } +}; diff --git a/sbin/etherswitchcfg/ifmedia.c b/sbin/etherswitchcfg/ifmedia.c new file mode 100644 index 0000000..49881fe --- /dev/null +++ b/sbin/etherswitchcfg/ifmedia.c @@ -0,0 +1,812 @@ +/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ +/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 221954 2011-05-15 12:51:00Z marius $ */ + +/* + * Copyright (c) 1997 Jason R. Thorpe. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Jason R. Thorpe. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ +/* + * based on sbin/ifconfig/ifmedia.c r221954 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +void domediaopt(const char *, int, int); +int get_media_subtype(int, const char *); +int get_media_mode(int, const char *); +int get_media_options(int, const char *); +int lookup_media_word(struct ifmedia_description *, const char *); +void print_media_word(int, int); +void print_media_word_ifconfig(int); + +#if 0 +static struct ifmedia_description *get_toptype_desc(int); +static struct ifmedia_type_to_subtype *get_toptype_ttos(int); +static struct ifmedia_description *get_subtype_desc(int, + struct ifmedia_type_to_subtype *ttos); + +#define IFM_OPMODE(x) \ + ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \ + IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \ + IFM_IEEE80211_MBSS)) +#define IFM_IEEE80211_STA 0 + +static void +media_status(int s) +{ + struct ifmediareq ifmr; + int *media_list, i; + + (void) memset(&ifmr, 0, sizeof(ifmr)); + (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + /* + * Interface doesn't support SIOC{G,S}IFMEDIA. + */ + return; + } + + if (ifmr.ifm_count == 0) { + warnx("%s: no media types?", name); + return; + } + + media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); + if (media_list == NULL) + err(1, "malloc"); + ifmr.ifm_ulist = media_list; + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + + printf("\tmedia: "); + print_media_word(ifmr.ifm_current, 1); + if (ifmr.ifm_active != ifmr.ifm_current) { + putchar(' '); + putchar('('); + print_media_word(ifmr.ifm_active, 0); + putchar(')'); + } + + putchar('\n'); + + if (ifmr.ifm_status & IFM_AVALID) { + printf("\tstatus: "); + switch (IFM_TYPE(ifmr.ifm_active)) { + case IFM_ETHER: + case IFM_ATM: + if (ifmr.ifm_status & IFM_ACTIVE) + printf("active"); + else + printf("no carrier"); + break; + + case IFM_FDDI: + case IFM_TOKEN: + if (ifmr.ifm_status & IFM_ACTIVE) + printf("inserted"); + else + printf("no ring"); + break; + + case IFM_IEEE80211: + if (ifmr.ifm_status & IFM_ACTIVE) { + /* NB: only sta mode associates */ + if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) + printf("associated"); + else + printf("running"); + } else + printf("no carrier"); + break; + } + putchar('\n'); + } + + if (ifmr.ifm_count > 0 && supmedia) { + printf("\tsupported media:\n"); + for (i = 0; i < ifmr.ifm_count; i++) { + printf("\t\t"); + print_media_word_ifconfig(media_list[i]); + putchar('\n'); + } + } + + free(media_list); +} + +struct ifmediareq * +ifmedia_getstate(int s) +{ + static struct ifmediareq *ifmr = NULL; + int *mwords; + + if (ifmr == NULL) { + ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); + if (ifmr == NULL) + err(1, "malloc"); + + (void) memset(ifmr, 0, sizeof(struct ifmediareq)); + (void) strncpy(ifmr->ifm_name, name, + sizeof(ifmr->ifm_name)); + + ifmr->ifm_count = 0; + ifmr->ifm_ulist = NULL; + + /* + * We must go through the motions of reading all + * supported media because we need to know both + * the current media type and the top-level type. + */ + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { + err(1, "SIOCGIFMEDIA"); + } + + if (ifmr->ifm_count == 0) + errx(1, "%s: no media types?", name); + + mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); + if (mwords == NULL) + err(1, "malloc"); + + ifmr->ifm_ulist = mwords; + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } + + return ifmr; +} + +static void +setifmediacallback(int s, void *arg) +{ + struct ifmediareq *ifmr = (struct ifmediareq *)arg; + static int did_it = 0; + + if (!did_it) { + ifr.ifr_media = ifmr->ifm_current; + if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) + err(1, "SIOCSIFMEDIA (media)"); + free(ifmr->ifm_ulist); + free(ifmr); + did_it = 1; + } +} + +static void +setmedia(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int subtype; + + ifmr = ifmedia_getstate(s); + + /* + * We are primarily concerned with the top-level type. + * However, "current" may be only IFM_NONE, so we just look + * for the top-level type in the first "supported type" + * entry. + * + * (I'm assuming that all supported media types for a given + * interface will be the same top-level type..) + */ + subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) | + IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediaopt(const char *val, int d, int s, const struct afswtch *afp) +{ + + domediaopt(val, 0, s); +} + +static void +unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) +{ + + domediaopt(val, 1, s); +} + +static void +domediaopt(const char *val, int clear, int s) +{ + struct ifmediareq *ifmr; + int options; + + ifmr = ifmedia_getstate(s); + + options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = ifmr->ifm_current; + if (clear) + ifr.ifr_media &= ~options; + else { + if (options & IFM_HDX) { + ifr.ifr_media &= ~IFM_FDX; + options &= ~IFM_HDX; + } + ifr.ifr_media |= options; + } + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediainst(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int inst; + + ifmr = ifmedia_getstate(s); + + inst = atoi(val); + if (inst < 0 || inst > (int)IFM_INST_MAX) + errx(1, "invalid media instance: %s", val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediamode(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int mode; + + ifmr = ifmedia_getstate(s); + + mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} +#endif + +/********************************************************************** + * A good chunk of this is duplicated from sys/net/ifmedia.c + **********************************************************************/ + +static struct ifmedia_description ifm_type_descriptions[] = + IFM_TYPE_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_descriptions[] = + IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_aliases[] = + IFM_SUBTYPE_ETHERNET_ALIASES; + +static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = + IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_tokenring_descriptions[] = + IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_tokenring_aliases[] = + IFM_SUBTYPE_TOKENRING_ALIASES; + +static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = + IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_fddi_descriptions[] = + IFM_SUBTYPE_FDDI_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_fddi_aliases[] = + IFM_SUBTYPE_FDDI_ALIASES; + +static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = + IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = + IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ieee80211_aliases[] = + IFM_SUBTYPE_IEEE80211_ALIASES; + +static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = + IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; + +struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = + IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; + +struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = + IFM_SUBTYPE_IEEE80211_MODE_ALIASES; + +static struct ifmedia_description ifm_subtype_atm_descriptions[] = + IFM_SUBTYPE_ATM_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_atm_aliases[] = + IFM_SUBTYPE_ATM_ALIASES; + +static struct ifmedia_description ifm_subtype_atm_option_descriptions[] = + IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_shared_descriptions[] = + IFM_SUBTYPE_SHARED_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_shared_aliases[] = + IFM_SUBTYPE_SHARED_ALIASES; + +static struct ifmedia_description ifm_shared_option_descriptions[] = + IFM_SHARED_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_shared_option_aliases[] = + IFM_SHARED_OPTION_ALIASES; + +struct ifmedia_type_to_subtype { + struct { + struct ifmedia_description *desc; + int alias; + } subtypes[5]; + struct { + struct ifmedia_description *desc; + int alias; + } options[4]; + struct { + struct ifmedia_description *desc; + int alias; + } modes[3]; +}; + +/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ +static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_ethernet_descriptions[0], 0 }, + { &ifm_subtype_ethernet_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_ethernet_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_tokenring_descriptions[0], 0 }, + { &ifm_subtype_tokenring_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_tokenring_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_fddi_descriptions[0], 0 }, + { &ifm_subtype_fddi_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_fddi_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_ieee80211_descriptions[0], 0 }, + { &ifm_subtype_ieee80211_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, + { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_atm_descriptions[0], 0 }, + { &ifm_subtype_atm_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_atm_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, +}; + +int +get_media_subtype(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int rval, i; + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media type 0x%x", type); + + for (i = 0; ttos->subtypes[i].desc != NULL; i++) { + rval = lookup_media_word(ttos->subtypes[i].desc, val); + if (rval != -1) + return (rval); + } + errx(1, "unknown media subtype: %s", val); + /*NOTREACHED*/ +} + +int +get_media_mode(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int rval, i; + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media mode 0x%x", type); + + for (i = 0; ttos->modes[i].desc != NULL; i++) { + rval = lookup_media_word(ttos->modes[i].desc, val); + if (rval != -1) + return (rval); + } + return -1; +} + +int +get_media_options(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + char *optlist, *optptr; + int option = 0, i, rval = 0; + + /* We muck with the string, so copy it. */ + optlist = strdup(val); + if (optlist == NULL) + err(1, "strdup"); + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media type 0x%x", type); + + /* + * Look up the options in the user-provided comma-separated + * list. + */ + optptr = optlist; + for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { + for (i = 0; ttos->options[i].desc != NULL; i++) { + option = lookup_media_word(ttos->options[i].desc, optptr); + if (option != -1) + break; + } + if (option == 0) + errx(1, "unknown option: %s", optptr); + rval |= option; + } + + free(optlist); + return (rval); +} + +int +lookup_media_word(struct ifmedia_description *desc, const char *val) +{ + + for (; desc->ifmt_string != NULL; desc++) + if (strcasecmp(desc->ifmt_string, val) == 0) + return (desc->ifmt_word); + + return (-1); +} + +static struct ifmedia_description *get_toptype_desc(int ifmw) +{ + struct ifmedia_description *desc; + + for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) + if (IFM_TYPE(ifmw) == desc->ifmt_word) + break; + + return desc; +} + +static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (IFM_TYPE(ifmw) == desc->ifmt_word) + break; + + return ttos; +} + +static struct ifmedia_description *get_subtype_desc(int ifmw, + struct ifmedia_type_to_subtype *ttos) +{ + int i; + struct ifmedia_description *desc; + + for (i = 0; ttos->subtypes[i].desc != NULL; i++) { + if (ttos->subtypes[i].alias) + continue; + for (desc = ttos->subtypes[i].desc; + desc->ifmt_string != NULL; desc++) { + if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) + return desc; + } + } + + return NULL; +} + +static struct ifmedia_description *get_mode_desc(int ifmw, + struct ifmedia_type_to_subtype *ttos) +{ + int i; + struct ifmedia_description *desc; + + for (i = 0; ttos->modes[i].desc != NULL; i++) { + if (ttos->modes[i].alias) + continue; + for (desc = ttos->modes[i].desc; + desc->ifmt_string != NULL; desc++) { + if (IFM_MODE(ifmw) == desc->ifmt_word) + return desc; + } + } + + return NULL; +} + +void +print_media_word(int ifmw, int print_toptype) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int seen_option = 0, i; + + /* Find the top-level interface type. */ + desc = get_toptype_desc(ifmw); + ttos = get_toptype_ttos(ifmw); + if (desc->ifmt_string == NULL) { + printf(""); + return; + } else if (print_toptype) { + printf("%s", desc->ifmt_string); + } + + /* + * Don't print the top-level type; it's not like we can + * change it, or anything. + */ + + /* Find subtype. */ + desc = get_subtype_desc(ifmw, ttos); + if (desc == NULL) { + printf(""); + return; + } + + if (print_toptype) + putchar(' '); + + printf("%s", desc->ifmt_string); + + if (print_toptype) { + desc = get_mode_desc(ifmw, ttos); + if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) + printf(" mode %s", desc->ifmt_string); + } + + /* Find options. */ + for (i = 0; ttos->options[i].desc != NULL; i++) { + if (ttos->options[i].alias) + continue; + for (desc = ttos->options[i].desc; + desc->ifmt_string != NULL; desc++) { + if (ifmw & desc->ifmt_word) { + if (seen_option == 0) + printf(" <"); + printf("%s%s", seen_option++ ? "," : "", + desc->ifmt_string); + } + } + } + printf("%s", seen_option ? ">" : ""); + + if (print_toptype && IFM_INST(ifmw) != 0) + printf(" instance %d", IFM_INST(ifmw)); +} + +void +print_media_word_ifconfig(int ifmw) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int seen_option = 0, i; + + /* Find the top-level interface type. */ + desc = get_toptype_desc(ifmw); + ttos = get_toptype_ttos(ifmw); + if (desc->ifmt_string == NULL) { + printf(""); + return; + } + + /* + * Don't print the top-level type; it's not like we can + * change it, or anything. + */ + + /* Find subtype. */ + desc = get_subtype_desc(ifmw, ttos); + if (desc == NULL) { + printf(""); + return; + } + + printf("media %s", desc->ifmt_string); + + desc = get_mode_desc(ifmw, ttos); + if (desc != NULL) + printf(" mode %s", desc->ifmt_string); + + /* Find options. */ + for (i = 0; ttos->options[i].desc != NULL; i++) { + if (ttos->options[i].alias) + continue; + for (desc = ttos->options[i].desc; + desc->ifmt_string != NULL; desc++) { + if (ifmw & desc->ifmt_word) { + if (seen_option == 0) + printf(" mediaopt "); + printf("%s%s", seen_option++ ? "," : "", + desc->ifmt_string); + } + } + } + + if (IFM_INST(ifmw) != 0) + printf(" instance %d", IFM_INST(ifmw)); +} + +/********************************************************************** + * ...until here. + **********************************************************************/ --Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4 Content-Disposition: attachment; filename=miiproxy.patch Content-Type: application/octet-stream; name="miiproxy.patch" Content-Transfer-Encoding: 7bit diff --git a/sys/dev/etherswitch/mdio.c b/sys/dev/etherswitch/mdio.c new file mode 100644 index 0000000..9302075 --- /dev/null +++ b/sys/dev/etherswitch/mdio.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include + +#include + +#include "mdio_if.h" + +static void +mdio_identify(driver_t *driver, device_t parent) +{ + if (device_find_child(parent, mdio_driver.name, -1) == NULL) + BUS_ADD_CHILD(parent, 0, mdio_driver.name, -1); +} + +static int +mdio_probe(device_t dev) +{ + device_set_desc(dev, "MDIO"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +mdio_attach(device_t dev) +{ + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + return (bus_generic_attach(dev)); +} + +static int +mdio_detach(device_t dev) +{ + bus_generic_detach(dev); + return (0); +} + +static int +mdio_readreg(device_t dev, int phy, int reg) +{ + return MDIO_READREG(device_get_parent(dev), phy, reg); +} + +static int +mdio_writereg(device_t dev, int phy, int reg, int val) +{ + return MDIO_WRITEREG(device_get_parent(dev), phy, reg, val); +} + +static int +mdio_print_child(device_t dev, device_t child) +{ + int retval; + + retval = bus_print_child_header(dev, child); + retval += bus_print_child_footer(dev, child); + + return (retval); +} + +static int +mdio_read_ivar(device_t dev, device_t child __unused, int which, + uintptr_t *result) +{ + struct miibus_ivars *ivars; + + ivars = device_get_ivars(dev); + switch (which) { + default: + return (ENOENT); + } + return (0); +} + +static int +mdio_child_pnpinfo_str(device_t dev __unused, device_t child, char *buf, + size_t buflen) +{ + buf[0] = '\0'; + return (0); +} + +static int +mdio_child_location_str(device_t dev __unused, device_t child, char *buf, + size_t buflen) +{ + buf[0] = '\0'; + return (0); +} + +static void +mdio_hinted_child(device_t dev, const char *name, int unit) +{ + device_add_child(dev, name, unit); +} + +static device_method_t mdio_methods[] = { + /* device interface */ + DEVMETHOD(device_identify, mdio_identify), + DEVMETHOD(device_probe, mdio_probe), + DEVMETHOD(device_attach, mdio_attach), + DEVMETHOD(device_detach, mdio_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* bus interface */ + DEVMETHOD(bus_print_child, mdio_print_child), + DEVMETHOD(bus_read_ivar, mdio_read_ivar), + DEVMETHOD(bus_child_pnpinfo_str, mdio_child_pnpinfo_str), + DEVMETHOD(bus_child_location_str, mdio_child_location_str), + DEVMETHOD(bus_add_child, device_add_child_ordered), + DEVMETHOD(bus_hinted_child, mdio_hinted_child), + + /* MDIO access */ + DEVMETHOD(mdio_readreg, mdio_readreg), + DEVMETHOD(mdio_writereg, mdio_writereg), + + DEVMETHOD_END +}; + +driver_t mdio_driver = { + "mdio", + mdio_methods, + 0 +}; + +devclass_t mdio_devclass; + diff --git a/sys/dev/etherswitch/mdio.h b/sys/dev/etherswitch/mdio.h new file mode 100644 index 0000000..52eddbd --- /dev/null +++ b/sys/dev/etherswitch/mdio.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 _DEV_MII_MDIO_H_ +#define _DEV_MII_MDIO_H_ + +extern driver_t mdio_driver; +extern devclass_t mdio_devclass; + +#endif diff --git a/sys/dev/etherswitch/mdio_if.m b/sys/dev/etherswitch/mdio_if.m new file mode 100644 index 0000000..9aedd92 --- /dev/null +++ b/sys/dev/etherswitch/mdio_if.m @@ -0,0 +1,24 @@ +# $FreeBSD$ + +#include + +INTERFACE mdio; + +# +# Read register from device on MDIO bus +# +METHOD int readreg { + device_t dev; + int phy; + int reg; +}; + +# +# Write register to device on MDIO bus +# +METHOD int writereg { + device_t dev; + int phy; + int reg; + int val; +}; diff --git a/sys/dev/etherswitch/miiproxy.c b/sys/dev/etherswitch/miiproxy.c new file mode 100644 index 0000000..2791082 --- /dev/null +++ b/sys/dev/etherswitch/miiproxy.c @@ -0,0 +1,437 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mdio_if.h" +#include "miibus_if.h" + + +MALLOC_DECLARE(M_MIIPROXY); +MALLOC_DEFINE(M_MIIPROXY, "miiproxy", "miiproxy data structures"); + +driver_t miiproxy_driver; +driver_t mdioproxy_driver; + +struct miiproxy_softc { + device_t parent; + device_t proxy; + device_t mdio; + miiproxy_attach_callback_t attach_callback; + void *attach_arg; +}; + +struct mdioproxy_softc { +}; + +/* + * The rendevous data structures and functions allow two device endpoints to + * match up, so that the proxy endpoint can be associated with a target + * endpoint. The proxy has to know the device name of the target that it + * wants to associate with, for example through a hint. The rendevous code + * makes no assumptions about the devices that want to meet. + */ +struct rendevous_entry; + +enum rendevous_op { + RENDEVOUS_ATTACH, + RENDEVOUS_DETACH +}; + +typedef int (*rendevous_callback_t)(enum rendevous_op, + struct rendevous_entry *); + +static SLIST_HEAD(rendevoushead, rendevous_entry) rendevoushead = + SLIST_HEAD_INITIALIZER(rendevoushead); + +struct rendevous_endpoint { + device_t device; + const char *name; + rendevous_callback_t callback; +}; + +struct rendevous_entry { + SLIST_ENTRY(rendevous_entry) entries; + struct rendevous_endpoint proxy; + struct rendevous_endpoint target; +}; + +/* + * Call the callback routines for both the proxy and the target. If either + * returns an error, undo the attachment. + */ +static int +rendevous_attach(struct rendevous_entry *e, struct rendevous_endpoint *ep) +{ + int error; + + error = e->proxy.callback(RENDEVOUS_ATTACH, e); + if (error == 0) + error = e->target.callback(RENDEVOUS_ATTACH, e); + if (error != 0) { + e->proxy.callback(RENDEVOUS_DETACH, e); + ep->device = NULL; + ep->callback = NULL; + } + return (error); +} + +/* + * Create an entry for the proxy in the rendevous list. The name parameter + * indicates the name of the device that is the target endpoint for this + * rendevous. The callback will be invoked as soon as the target is + * registered: either immediately if the target registered itself earlier, + * or once the target registers. + */ +static int +rendevous_register_proxy(device_t dev, const char *name, + rendevous_callback_t callback) +{ + struct rendevous_entry *e; + + KASSERT(callback != NULL, ("callback must not be NULL")); + SLIST_FOREACH(e, &rendevoushead, entries) { + if (strcmp(name, e->target.name) == 0) { + /* the target is already attached */ + e->proxy.name = device_get_nameunit(dev); + e->proxy.device = dev; + e->proxy.callback = callback; + return (rendevous_attach(e, &e->proxy)); + } + } + e = malloc(sizeof(*e), M_MIIPROXY, M_WAITOK | M_ZERO); + e->proxy.name = device_get_nameunit(dev); + e->proxy.device = dev; + e->proxy.callback = callback; + e->target.name = name; + SLIST_INSERT_HEAD(&rendevoushead, e, entries); + return (0); +} + +/* + * Create an entry in the rendevous list for the target. The callback will + * be called once the proxy has registered. + */ +static int +rendevous_register_target(device_t dev, rendevous_callback_t callback) +{ + struct rendevous_entry *e; + const char *name; + + KASSERT(callback != NULL, ("callback must not be NULL")); + name = device_get_nameunit(dev); + SLIST_FOREACH(e, &rendevoushead, entries) { + if (strcmp(name, e->target.name) == 0) { + e->target.device = dev; + e->target.callback = callback; + return (rendevous_attach(e, &e->target)); + } + } + e = malloc(sizeof(*e), M_MIIPROXY, M_WAITOK | M_ZERO); + e->target.name = name; + e->target.device = dev; + e->target.callback = callback; + SLIST_INSERT_HEAD(&rendevoushead, e, entries); + return (0); +} + +/* + * Remove the registration for the proxy. + */ +static int +rendevous_unregister_proxy(device_t dev) +{ + struct rendevous_entry *e; + int error = 0; + + SLIST_FOREACH(e, &rendevoushead, entries) { + if (e->proxy.device == dev) { + if (e->target.device == NULL) { + SLIST_REMOVE(&rendevoushead, e, rendevous_entry, entries); + free(e, M_MIIPROXY); + return (0); + } else { + e->proxy.callback(RENDEVOUS_DETACH, e); + e->target.callback(RENDEVOUS_DETACH, e); + } + e->proxy.device = NULL; + e->proxy.callback = NULL; + return (error); + } + } + return (ENOENT); +} + +/* + * Remove the registration for the target. + */ +static int +rendevous_unregister_target(device_t dev) +{ + struct rendevous_entry *e; + int error = 0; + + SLIST_FOREACH(e, &rendevoushead, entries) { + if (e->target.device == dev) { + if (e->proxy.device == NULL) { + SLIST_REMOVE(&rendevoushead, e, rendevous_entry, entries); + free(e, M_MIIPROXY); + return (0); + } else { + e->proxy.callback(RENDEVOUS_DETACH, e); + e->target.callback(RENDEVOUS_DETACH, e); + } + e->target.device = NULL; + e->target.callback = NULL; + return (error); + } + } + return (ENOENT); +} + +/* + * Functions of the proxy that is interposed between the ethernet interface + * driver and the miibus device. + */ + +static int +miiproxy_rendevous_callback(enum rendevous_op op, struct rendevous_entry *rendevous) +{ + struct miiproxy_softc *sc = device_get_softc(rendevous->proxy.device); + + switch (op) { + case RENDEVOUS_ATTACH: + sc->mdio = device_get_parent(rendevous->target.device); + (sc->attach_callback)(sc->attach_arg); + break; + case RENDEVOUS_DETACH: + sc->mdio = NULL; + /* detach miibus */ + } + return (0); +} + +static int +miiproxy_probe(device_t dev) +{ + device_set_desc(dev, "MII/MDIO proxy, MII side"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +miiproxy_attach(device_t dev) +{ + /* + * The ethernet interface needs to call mii_attach_proxy() to pass + * the relevant parameters for rendevous with the MDIO target. + */ + return (bus_generic_attach(dev)); +} + +static int +miiproxy_detach(device_t dev) +{ + rendevous_unregister_proxy(dev); + bus_generic_detach(dev); + return (0); +} + +static int +miiproxy_readreg(device_t dev, int phy, int reg) +{ + struct miiproxy_softc *sc = device_get_softc(dev); + + if (sc->mdio != NULL) + return (MDIO_READREG(sc->mdio, phy, reg)); + return (-1); +} + +static int +miiproxy_writereg(device_t dev, int phy, int reg, int val) +{ + struct miiproxy_softc *sc = device_get_softc(dev); + + if (sc->mdio != NULL) + return (MDIO_WRITEREG(sc->mdio, phy, reg, val)); + return (-1); +} + +static void +miiproxy_statchg(device_t dev) +{ + MIIBUS_STATCHG(device_get_parent(dev)); +} + +static void +miiproxy_linkchg(device_t dev) +{ + MIIBUS_LINKCHG(device_get_parent(dev)); +} + +static void +miiproxy_mediainit(device_t dev) +{ + MIIBUS_MEDIAINIT(device_get_parent(dev)); +} + +/* + * Functions for the MDIO target device driver. + */ +static int +mdioproxy_rendevous_callback(enum rendevous_op op, struct rendevous_entry *rendevous) +{ + return (0); +} + +static void +mdioproxy_identify(driver_t *driver, device_t parent) +{ + device_t child; + + if (device_find_child(parent, driver->name, -1) == NULL) { + child = BUS_ADD_CHILD(parent, 0, driver->name, -1); + } +} + +static int +mdioproxy_probe(device_t dev) +{ + device_set_desc(dev, "MII/MDIO proxy, MDIO side"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +mdioproxy_attach(device_t dev) +{ + rendevous_register_target(dev, mdioproxy_rendevous_callback); + return (bus_generic_attach(dev)); +} + +static int +mdioproxy_detach(device_t dev) +{ + rendevous_unregister_target(dev); + bus_generic_detach(dev); + return (0); +} + +/* + * Attach this proxy in place of miibus. The callback is called once all + * parts are in place, so that it can attach the miibus to the proxy device, + * and finish interface initialization. + */ +device_t +mii_attach_proxy(device_t dev, miiproxy_attach_callback_t cb, void *aa) +{ + struct miiproxy_softc *sc; + int error; + const char *name; + device_t miiproxy; + + if (resource_string_value(device_get_name(dev), + device_get_unit(dev), "mdio", &name) != 0) { + if (bootverbose) + printf("mii_attach_proxy: not attaching, no mdio" + " device hint for %s\n", device_get_nameunit(dev)); + return (NULL); + } + + miiproxy = device_add_child(dev, miiproxy_driver.name, -1); + error = bus_generic_attach(dev); + if (error != 0) { + device_printf(dev, "can't attach miiproxy\n"); + return (NULL); + } + sc = device_get_softc(miiproxy); + sc->parent = dev; + sc->proxy = miiproxy; + sc->attach_callback = cb; + sc->attach_arg = aa; + rendevous_register_proxy(miiproxy, name, miiproxy_rendevous_callback); + return (miiproxy); +} + +static device_method_t miiproxy_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, miiproxy_probe), + DEVMETHOD(device_attach, miiproxy_attach), + DEVMETHOD(device_detach, miiproxy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* MII interface */ + DEVMETHOD(miibus_readreg, miiproxy_readreg), + DEVMETHOD(miibus_writereg, miiproxy_writereg), + DEVMETHOD(miibus_statchg, miiproxy_statchg), + DEVMETHOD(miibus_linkchg, miiproxy_linkchg), + DEVMETHOD(miibus_mediainit, miiproxy_mediainit), + + DEVMETHOD_END +}; + +static device_method_t mdioproxy_methods[] = { + /* device interface */ + DEVMETHOD(device_identify, mdioproxy_identify), + DEVMETHOD(device_probe, mdioproxy_probe), + DEVMETHOD(device_attach, mdioproxy_attach), + DEVMETHOD(device_detach, mdioproxy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(miiproxy, miiproxy_driver, miiproxy_methods, + sizeof(struct miiproxy_softc)); +DEFINE_CLASS_0(mdioproxy, mdioproxy_driver, mdioproxy_methods, + sizeof(struct mdioproxy_softc)); + +devclass_t miiproxy_devclass; +static devclass_t mdioproxy_devclass; + +DRIVER_MODULE(mdioproxy, mdio, mdioproxy_driver, mdioproxy_devclass, 0, 0); +DRIVER_MODULE(miibus, miiproxy, miibus_driver, miibus_devclass, 0, 0); +MODULE_VERSION(miiproxy, 1); +MODULE_DEPEND(miiproxy, miibus, 1, 1, 1); diff --git a/sys/dev/etherswitch/miiproxy.h b/sys/dev/etherswitch/miiproxy.h new file mode 100644 index 0000000..5b8ee7c --- /dev/null +++ b/sys/dev/etherswitch/miiproxy.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 _DEV_ETHERSWITCH_MIIPROXY_H_ +#define _DEV_ETHERSWITCH_MIIPROXY_H_ + +typedef void (*miiproxy_attach_callback_t)(void *); + +extern devclass_t miiproxy_devclass; +extern driver_t miiproxy_driver; + +device_t mii_attach_proxy(device_t dev, miiproxy_attach_callback_t cb, void *aa); + +#endif diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 0154ae2..3dd2e15 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -72,8 +72,18 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#if defined(ARGE_MDIO) +#include +#include +#include "mdio_if.h" +#endif + + MODULE_DEPEND(arge, ether, 1, 1, 1); MODULE_DEPEND(arge, miibus, 1, 1, 1); +MODULE_VERSION(arge, 1); #include "miibus_if.h" @@ -102,6 +112,7 @@ typedef enum { #endif static int arge_attach(device_t); +static int arge_attach_finish(struct arge_softc *sc); static int arge_detach(device_t); static void arge_flush_ddr(struct arge_softc *); static int arge_ifmedia_upd(struct ifnet *); @@ -134,6 +145,8 @@ static void arge_intr(void *); static int arge_intr_filter(void *); static void arge_tick(void *); +static void arge_hinted_child(device_t bus, const char *dname, int dunit); + /* * ifmedia callbacks for multiPHY MAC */ @@ -160,6 +173,10 @@ static device_method_t arge_methods[] = { DEVMETHOD(miibus_writereg, arge_miibus_writereg), DEVMETHOD(miibus_statchg, arge_miibus_statchg), + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + DEVMETHOD(bus_hinted_child, arge_hinted_child), + DEVMETHOD_END }; @@ -174,6 +191,37 @@ static devclass_t arge_devclass; DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0); DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); +#if defined(ARGE_MDIO) +static int argemdio_probe(device_t); +static int argemdio_attach(device_t); +static int argemdio_detach(device_t); + +/* + * Declare an additional, separate driver for accessing the MDIO bus. + */ +static device_method_t argemdio_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, argemdio_probe), + DEVMETHOD(device_attach, argemdio_attach), + DEVMETHOD(device_detach, argemdio_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + + /* MDIO access */ + DEVMETHOD(mdio_readreg, arge_miibus_readreg), + DEVMETHOD(mdio_writereg, arge_miibus_writereg), +}; + +DEFINE_CLASS_0(argemdio, argemdio_driver, argemdio_methods, + sizeof(struct arge_softc)); +static devclass_t argemdio_devclass; + +DRIVER_MODULE(miiproxy, arge, miiproxy_driver, miiproxy_devclass, 0, 0); +DRIVER_MODULE(argemdio, nexus, argemdio_driver, argemdio_devclass, 0, 0); +DRIVER_MODULE(mdio, argemdio, mdio_driver, mdio_devclass, 0, 0); +#endif + /* * RedBoot passes MAC address to entry point as environment * variable. platfrom_start parses it and stores in this variable @@ -234,15 +282,22 @@ arge_attach_sysctl(device_t dev) #endif } +#if defined(ARGE_MDIO) +static void +arge_attach_proxy(void *aa) +{ + arge_attach_finish(aa); +} +#endif + static int arge_attach(device_t dev) { - uint8_t eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; struct arge_softc *sc; - int error = 0, rid, phymask; + int error = 0, rid; uint32_t reg, rnd; - int is_base_mac_empty, i, phys_total; + int is_base_mac_empty, i; uint32_t hint; long eeprom_mac_addr = 0; @@ -277,18 +332,18 @@ arge_attach(device_t dev) * Get which PHY of 5 available we should use for this unit */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "phymask", &phymask) != 0) { + "phymask", &sc->arge_phymask) != 0) { /* * Use port 4 (WAN) for GE0. For any other port use * its PHY the same as its unit number */ if (sc->arge_mac_unit == 0) - phymask = (1 << 4); + sc->arge_phymask = (1 << 4); else /* Use all phys up to 4 */ - phymask = (1 << 4) - 1; + sc->arge_phymask = (1 << 4) - 1; - device_printf(dev, "No PHY specified, using mask %d\n", phymask); + device_printf(dev, "No PHY specified, using mask %d\n", sc->arge_phymask); } /* @@ -313,8 +368,6 @@ arge_attach(device_t dev) else sc->arge_duplex_mode = 0; - sc->arge_phymask = phymask; - mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0); @@ -323,7 +376,7 @@ arge_attach(device_t dev) /* Map control/status registers. */ sc->arge_rid = 0; sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->arge_rid, RF_ACTIVE); + &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE); if (sc->arge_res == NULL) { device_printf(dev, "couldn't map memory\n"); @@ -371,8 +424,8 @@ arge_attach(device_t dev) is_base_mac_empty = 1; for (i = 0; i < ETHER_ADDR_LEN; i++) { - eaddr[i] = ar711_base_mac[i] & 0xff; - if (eaddr[i] != 0) + sc->arge_eaddr[i] = ar711_base_mac[i] & 0xff; + if (sc->arge_eaddr[i] != 0) is_base_mac_empty = 0; } @@ -385,16 +438,15 @@ arge_attach(device_t dev) "Generating random ethernet address.\n"); rnd = arc4random(); - eaddr[0] = 'b'; - eaddr[1] = 's'; - eaddr[2] = 'd'; - eaddr[3] = (rnd >> 24) & 0xff; - eaddr[4] = (rnd >> 16) & 0xff; - eaddr[5] = (rnd >> 8) & 0xff; + sc->arge_eaddr[0] = 'b'; + sc->arge_eaddr[1] = 's'; + sc->arge_eaddr[2] = 'd'; + sc->arge_eaddr[3] = (rnd >> 24) & 0xff; + sc->arge_eaddr[4] = (rnd >> 16) & 0xff; + sc->arge_eaddr[5] = (rnd >> 8) & 0xff; } - if (sc->arge_mac_unit != 0) - eaddr[5] += sc->arge_mac_unit; + sc->arge_eaddr[5] += sc->arge_mac_unit; if (arge_dma_alloc(sc) != 0) { error = ENXIO; @@ -423,19 +475,23 @@ arge_attach(device_t dev) ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536); +#if !defined(ARGE_MDIO) /* Reset MII bus */ ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); DELAY(100); ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); DELAY(100); +#endif /* * Set all Ethernet address registers to the same initial values * set all four addresses to 66-88-aa-cc-dd-ee */ - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, - (eaddr[2] << 24) | (eaddr[3] << 16) | (eaddr[4] << 8) | eaddr[5]); - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (eaddr[0] << 8) | eaddr[1]); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, (sc->arge_eaddr[2] << 24) + | (sc->arge_eaddr[3] << 16) | (sc->arge_eaddr[4] << 8) + | sc->arge_eaddr[5]); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (sc->arge_eaddr[0] << 8) + | sc->arge_eaddr[1]); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0, FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT); @@ -458,30 +514,44 @@ arge_attach(device_t dev) ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, FIFO_RX_FILTMASK_DEFAULT); - /* - * Check if we have single-PHY MAC or multi-PHY - */ - phys_total = 0; - for (i = 0; i < ARGE_NPHY; i++) - if (phymask & (1 << i)) - phys_total ++; +#if defined(ARGE_MDIO) + sc->arge_miiproxy = mii_attach_proxy(sc->arge_dev, arge_attach_proxy, sc); + if (sc->arge_miiproxy == NULL) + return (arge_attach_finish(sc)); +#else + return (arge_attach_finish(sc)); +#endif +fail: + if (error) + arge_detach(dev); - if (phys_total == 0) { - error = EINVAL; - goto fail; - } + return (error); +} - if (phys_total == 1) { - /* Do MII setup. */ - error = mii_attach(dev, &sc->arge_miibus, ifp, - arge_ifmedia_upd, arge_ifmedia_sts, BMSR_DEFCAPMASK, - MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; +static int +arge_attach_finish(struct arge_softc *sc) +{ + int error, phy; + + device_printf(sc->arge_dev, "finishing attachment, phymask %04x" + ", proxy %s \n", sc->arge_phymask, sc->arge_miiproxy == NULL ? + "null" : "set"); + for (phy = 0; phy < ARGE_NPHY; phy++) { + if (((1 << phy) & sc->arge_phymask) != 0) { + error = mii_attach(sc->arge_miiproxy != NULL ? + sc->arge_miiproxy : sc->arge_dev, + &sc->arge_miibus, sc->arge_ifp, + arge_ifmedia_upd, arge_ifmedia_sts, + BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + if (error != 0) { + device_printf(sc->arge_dev, "unable to attach" + " PHY %d: %d\n", phy, error); + goto fail; + } } } - else { + if (sc->arge_miibus == NULL) { + /* no PHY, so use hard-coded values */ ifmedia_init(&sc->arge_ifmedia, 0, arge_multiphy_mediachange, arge_multiphy_mediastatus); @@ -494,24 +564,23 @@ arge_attach(device_t dev) } /* Call MI attach routine. */ - ether_ifattach(ifp, eaddr); + ether_ifattach(sc->arge_ifp, sc->arge_eaddr); /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, + error = bus_setup_intr(sc->arge_dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, arge_intr_filter, arge_intr, sc, &sc->arge_intrhand); if (error) { - device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); + device_printf(sc->arge_dev, "couldn't set up irq\n"); + ether_ifdetach(sc->arge_ifp); goto fail; } /* setup sysctl variables */ - arge_attach_sysctl(dev); - + arge_attach_sysctl(sc->arge_dev); fail: if (error) - arge_detach(dev); + arge_detach(sc->arge_dev); return (error); } @@ -542,6 +611,9 @@ arge_detach(device_t dev) if (sc->arge_miibus) device_delete_child(dev, sc->arge_miibus); + if (sc->arge_miiproxy) + device_delete_child(dev, sc->arge_miiproxy); + bus_generic_detach(dev); if (sc->arge_intrhand) @@ -592,6 +664,13 @@ arge_shutdown(device_t dev) return (0); } +static void +arge_hinted_child(device_t bus, const char *dname, int dunit) +{ + BUS_ADD_CHILD(bus, 0, dname, dunit); + device_printf(bus, "hinted child %s%d\n", dname, dunit); +} + static int arge_miibus_readreg(device_t dev, int phy, int reg) { @@ -600,16 +679,13 @@ arge_miibus_readreg(device_t dev, int phy, int reg) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - if ((sc->arge_phymask & (1 << phy)) == 0) - return (0); - mtx_lock(&miibus_mtx); - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); - ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); i = ARGE_MII_TIMEOUT; - while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); @@ -620,8 +696,8 @@ arge_miibus_readreg(device_t dev, int phy, int reg) return (-1); } - result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); mtx_unlock(&miibus_mtx); ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, @@ -638,19 +714,15 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - - if ((sc->arge_phymask & (1 << phy)) == 0) - return (-1); - ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value=%04x\n", __func__, phy, reg, data); mtx_lock(&miibus_mtx); - ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); - ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); i = ARGE_MII_TIMEOUT; - while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); @@ -715,6 +787,8 @@ arge_set_pll(struct arge_softc *sc, int media, int duplex) uint32_t fifo_tx; int if_speed; + ARGEDEBUG(sc, ARGE_DBG_MII, "set_pll(%04x, %s)\n", media, + duplex == IFM_FDX ? "full" : "half"); cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); cfg &= ~(MAC_CFG2_IFACE_MODE_1000 | MAC_CFG2_IFACE_MODE_10_100 @@ -1923,3 +1997,47 @@ arge_multiphy_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) sc->arge_duplex_mode; } +#if defined(ARGE_MDIO) +static int +argemdio_probe(device_t dev) +{ + device_set_desc(dev, "Atheros AR71xx built-in ethernet interface, MDIO controller"); + return (0); +} + +static int +argemdio_attach(device_t dev) +{ + struct arge_softc *sc; + int error = 0; + + sc = device_get_softc(dev); + sc->arge_dev = dev; + sc->arge_mac_unit = device_get_unit(dev); + sc->arge_rid = 0; + sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE); + if (sc->arge_res == NULL) { + device_printf(dev, "couldn't map memory\n"); + error = ENXIO; + goto fail; + } + /* Reset MII bus */ + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); + DELAY(100); + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); + DELAY(100); + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + error = bus_generic_attach(dev); +fail: + return (error); +} + +static int +argemdio_detach(device_t dev) +{ + return (0); +} + +#endif diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index c1df678..dc3d931 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -67,15 +67,10 @@ #define ARGE_CLEAR_BITS(sc, reg, bits) \ ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) -/* - * MII registers access macros - */ -#define ARGE_MII_READ(reg) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) - -#define ARGE_MII_WRITE(reg, val) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) = (val) - +#define ARGE_MDIO_WRITE(_sc, _reg, _val) \ + ARGE_WRITE((_sc), (_reg), (_val)) +#define ARGE_MDIO_READ(_sc, _reg) \ + ARGE_READ((_sc), (_reg)) #define ARGE_DESC_EMPTY (1 << 31) #define ARGE_DESC_MORE (1 << 24) @@ -132,11 +127,14 @@ struct arge_softc { */ uint32_t arge_media_type; uint32_t arge_duplex_mode; + uint32_t arge_phymask; + uint8_t arge_eaddr[ETHER_ADDR_LEN]; struct resource *arge_res; int arge_rid; struct resource *arge_irq; void *arge_intrhand; device_t arge_miibus; + device_t arge_miiproxy; bus_dma_tag_t arge_parent_tag; bus_dma_tag_t arge_tag; struct mtx arge_mtx; @@ -148,7 +146,6 @@ struct arge_softc { int arge_detach; uint32_t arge_intr_status; int arge_mac_unit; - int arge_phymask; int arge_if_flags; uint32_t arge_debug; struct { --Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4 Content-Disposition: attachment; filename=etherswitch-complete.patch Content-Type: application/octet-stream; name="etherswitch-complete.patch" Content-Transfer-Encoding: 7bit diff --git a/sbin/Makefile b/sbin/Makefile index f9ba4ca..0cb421f 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -20,6 +20,7 @@ SUBDIR=adjkerntz \ dump \ dumpfs \ dumpon \ + etherswitchcfg \ ffsinfo \ fsck \ fsck_ffs \ diff --git a/sbin/etherswitchcfg/Makefile b/sbin/etherswitchcfg/Makefile new file mode 100644 index 0000000..d21c88b --- /dev/null +++ b/sbin/etherswitchcfg/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 5.4 (Berkeley) 6/5/91 +# $FreeBSD: head/sbin/comcontrol/Makefile 198236 2009-10-19 16:00:24Z ru $ + +PROG= etherswitchcfg +MAN= etherswitchcfg.8 +SRCS= etherswitchcfg.c ifmedia.c +CFLAGS+= -I${.CURDIR}/../../sys + +.include diff --git a/sbin/etherswitchcfg/etherswitchcfg.8 b/sbin/etherswitchcfg/etherswitchcfg.8 new file mode 100644 index 0000000..538950c --- /dev/null +++ b/sbin/etherswitchcfg/etherswitchcfg.8 @@ -0,0 +1,114 @@ +.\" $FreeBSD$ +.Dd December 15, 2011 +.Dt ETHERSWITCHCFG 8 +.Os +.Sh NAME +.Nm etherswitchcfg +.Nd configure a built-in Ethernet switch +.Sh SYNOPSIS +.Nm +.Op Fl "f control file" +.Ar info +.Nm +.Op Fl "f control file" +.Ar phy +.Ar phy.register[=value] +.Nm +.Op Fl "f control file" +.Ar port%d +.Ar command parameter +.Nm +.Op Fl "f control file" +.Ar reg +.Ar register[=value] +.Nm +.Op Fl "f control file" +.Ar vlangroup%d +.Ar command parameter +.Sh DESCRIPTION +The +.Nm +utility is used to configure an Ethernet switch built into the system. +.Nm +accepts a number of options: +.Bl -tag -width ".Fl f" -compact +.It Fl "f control file" +Specifies the +.Xr etherswitch 4 +control file that represents the switch to be configured. +It defaults to +.Li /dev/etherswitch0 . +.It Fl m +When reporting port information, also list available media options for +that port. +.It Fl v +Produce more verbose output. +Without this flag, lines that represent inactive or empty configuration +options are omitted. +.El +.Ss phy +The phy command provides access to the registers of the PHYs attached +to or integrated into the switch controller. +PHY registers are specified as phy.register, +where +.Ar phy +is usually the port number, and +.Ar register +is the register number. +Both can be provided as decimal, octal or hexadecimal numbers in any of the formats +understood by +.Xr strtol 4 . +To set the register value, use the form instance.register=value. +.Ss port +The port command selects one of the ports of the switch. +It supports the following commands: +.Bl -tag -width ".Ar vlangroup number" -compact +.It Ar vlangroup number +Sets the VLAN group number that is used to process incoming frames that are not tagged. +.It Ar media mediaspec +Specifies the physical media configuration to be configured for a port. +.It Ar mediaopt mediaoption +Specifies a list of media options for a port. See +.Xr ifconfig 8 +for details on +.Ar media and +.Ar mediaopt . +.El +.Ss reg +The reg command provides access to the registers of the switch controller. +.Ss vlangroup +The vlangroup command selects one of the VLAN groups for configuration. +It supports the following commands: +.Bl -tag -width ".Ar vlangroup" -compact +.It Ar vlan VID +Sets the VLAN ID (802.1q VID) for this VLAN group. +Frames transmitted on tagged member ports of this group will be tagged +with this VID. +Incoming frames carrying this tag will be forwarded according to the +configuration of this VLAN group. +.It Ar members port,... +Configures which ports are to be a member of this VLAN group. +The port numbers are given as a comma-separated list. +Each port can optionally be followed by +.Dq t +to indicate that frames on this port are tagged. +.El +.Sh FILES +.Bl -tag -width /dev/etherswitch? -compact +.It Pa /dev/etherswitch? +Control file for the ethernet switch driver. +.El +.Sh EXAMPLES +Configure VLAN group 1 with a VID of 2 and makes ports 0 and 5 members, +while excluding all other ports. +Port 5 will send and receive tagged frames, while port 0 will be untagged. +Incoming untagged frames on port 0 are assigned to vlangroup1. +.Dl # etherswitchcfg vlangroup1 vlan 2 members 0,5t port0 vlangroup 1 +.Sh SEE ALSO +.Xr etherswitch 4 +.Sh HISTORY +.Nm +first appeared in +.Fx 10.0 . +.Sh AUTHORS +.An Stefan Bethke diff --git a/sbin/etherswitchcfg/etherswitchcfg.c b/sbin/etherswitchcfg/etherswitchcfg.c new file mode 100644 index 0000000..e6129f3 --- /dev/null +++ b/sbin/etherswitchcfg/etherswitchcfg.c @@ -0,0 +1,511 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int get_media_subtype(int, const char *); +int get_media_mode(int, const char *); +int get_media_options(int, const char *); +int lookup_media_word(struct ifmedia_description *, const char *); +void print_media_word(int, int); +void print_media_word_ifconfig(int); + +/* some constants */ +#define IEEE802DOT1Q_VID_MAX 4094 +#define IFMEDIAREQ_NULISTENTRIES 256 + +enum cmdmode { + MODE_NONE = 0, + MODE_PORT, + MODE_VLANGROUP, + MODE_REGISTER, + MODE_PHYREG +}; + +struct cfg { + int fd; + int verbose; + int mediatypes; + const char *controlfile; + etherswitch_info_t info; + enum cmdmode mode; + int unit; +}; + +struct cmds { + enum cmdmode mode; + const char *name; + int args; + void (*f)(struct cfg *, char *argv[]); +}; +struct cmds cmds[]; + + +static void usage(void); + +static int +read_register(struct cfg *cfg, int r) +{ + struct etherswitch_reg er; + + er.reg = r; + if (ioctl(cfg->fd, IOETHERSWITCHGETREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETREG)"); + return (er.val); +} + +static void +write_register(struct cfg *cfg, int r, int v) +{ + struct etherswitch_reg er; + + er.reg = r; + er.val = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETREG)"); +} + +static int +read_phyregister(struct cfg *cfg, int phy, int reg) +{ + struct etherswitch_phyreg er; + + er.phy = phy; + er.reg = reg; + if (ioctl(cfg->fd, IOETHERSWITCHGETPHYREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPHYREG)"); + return (er.val); +} + +static void +write_phyregister(struct cfg *cfg, int phy, int reg, int val) +{ + struct etherswitch_phyreg er; + + er.phy = phy; + er.reg = reg; + er.val = val; + if (ioctl(cfg->fd, IOETHERSWITCHSETPHYREG, &er) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPHYREG)"); +} + +static void +set_port_vlangroup(struct cfg *cfg, char *argv[]) +{ + int v; + etherswitch_port_t p; + + v = strtol(argv[1], NULL, 0); + if (v < 0 || v >= cfg->info.es_nvlangroups) + errx(EX_USAGE, "vlangroup must be between 0 and %d", cfg->info.es_nvlangroups-1); + p.es_port = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + p.es_vlangroup = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_port_media(struct cfg *cfg, char *argv[]) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int subtype; + + bzero(&p, sizeof(p)); + p.es_port = cfg->unit; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + subtype = get_media_subtype(IFM_TYPE(ifm_ulist[0]), argv[1]); + p.es_ifr.ifr_media = (p.es_ifmr.ifm_current & IFM_IMASK) | + IFM_TYPE(ifm_ulist[0]) | subtype; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_port_mediaopt(struct cfg *cfg, char *argv[]) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int options; + + bzero(&p, sizeof(p)); + p.es_port = cfg->unit; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + options = get_media_options(IFM_TYPE(ifm_ulist[0]), argv[1]); + if (options == -1) + errx(EX_USAGE, "invalid media options \"%s\"", argv[1]); + if (options & IFM_HDX) { + p.es_ifr.ifr_media &= ~IFM_FDX; + options &= ~IFM_HDX; + } + p.es_ifr.ifr_media |= options; + if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); +} + +static void +set_vlangroup_vid(struct cfg *cfg, char *argv[]) +{ + int v; + etherswitch_vlangroup_t vg; + + v = strtol(argv[1], NULL, 0); + if (v < 0 || v >= IEEE802DOT1Q_VID_MAX) + errx(EX_USAGE, "vlan must be between 0 and %d", IEEE802DOT1Q_VID_MAX); + vg.es_vlangroup = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + vg.es_vid = v; + if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)"); +} + +static void +set_vlangroup_members(struct cfg *cfg, char *argv[]) +{ + etherswitch_vlangroup_t vg; + int member, untagged; + char *c, *d; + int v; + + member = untagged = 0; + if (strcmp(argv[1], "none") != 0) { + for (c=argv[1]; *c; c=d) { + v = strtol(c, &d, 0); + if (d == c) + break; + if (v < 0 || v >= cfg->info.es_nports) + errx(EX_USAGE, "Member port must be between 0 and %d", cfg->info.es_nports-1); + if (d[0] == ',' || d[0] == '\0' || + ((d[0] == 't' || d[0] == 'T') && (d[1] == ',' || d[1] == '\0'))) { + if (d[0] == 't' || d[0] == 'T') { + untagged &= ~ETHERSWITCH_PORTMASK(v); + d++; + } else + untagged |= ETHERSWITCH_PORTMASK(v); + member |= ETHERSWITCH_PORTMASK(v); + d++; + } else + errx(EX_USAGE, "Invalid members specification \"%s\"", d); + } + } + vg.es_vlangroup = cfg->unit; + if (ioctl(cfg->fd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + vg.es_member_ports = member; + vg.es_untagged_ports = untagged; + if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)"); +} + +static int +set_register(struct cfg *cfg, char *arg) +{ + int a, v; + char *c; + + a = strtol(arg, &c, 0); + if (c==arg) + return (1); + if (*c == '=') { + v = strtol(c+1, NULL, 0); + write_register(cfg, a, v); + } + printf("\treg 0x%04x=0x%04x\n", a, read_register(cfg, a)); + return (0); +} + +static int +set_phyregister(struct cfg *cfg, char *arg) +{ + int phy, reg, val; + char *c, *d; + + phy = strtol(arg, &c, 0); + if (c==arg) + return (1); + if (*c != '.') + return (1); + d = c+1; + reg = strtol(d, &c, 0); + if (d == c) + return (1); + if (*c == '=') { + val = strtol(c+1, NULL, 0); + write_phyregister(cfg, phy, reg, val); + } + printf("\treg %d.0x%02x=0x%04x\n", phy, reg, read_phyregister(cfg, phy, reg)); + return (0); +} + +static void +print_port(struct cfg *cfg, int port) +{ + etherswitch_port_t p; + int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; + int i; + + bzero(&p, sizeof(p)); + p.es_port = port; + p.es_ifmr.ifm_ulist = ifm_ulist; + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); + printf("port%d:\n", port); + printf("\tvlangroup: %d\n", p.es_vlangroup); + printf("\tmedia: "); + print_media_word(p.es_ifmr.ifm_current, 1); + if (p.es_ifmr.ifm_active != p.es_ifmr.ifm_current) { + putchar(' '); + putchar('('); + print_media_word(p.es_ifmr.ifm_active, 0); + putchar(')'); + } + putchar('\n'); + printf("\tstatus: %s\n", (p.es_ifmr.ifm_status & IFM_ACTIVE) != 0 ? "active" : "no carrier"); + if (cfg->mediatypes) { + printf("\tsupported media:\n"); + if (p.es_ifmr.ifm_count > IFMEDIAREQ_NULISTENTRIES) + p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; + for (i=0; ifd, IOETHERSWITCHGETVLANGROUP, &vg) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETVLANGROUP)"); + if (cfg->verbose == 0 && vg.es_member_ports == 0) + return; + printf("vlangroup%d:\n", vlangroup); + printf("\tvlan: %d\n", vg.es_vid); + printf("\tmembers "); + comma = 0; + if (vg.es_member_ports != 0) + for (i=0; iinfo.es_nports; i++) { + if ((vg.es_member_ports & ETHERSWITCH_PORTMASK(i)) != 0) { + if (comma) + printf(","); + printf("%d", i); + if ((vg.es_untagged_ports & ETHERSWITCH_PORTMASK(i)) == 0) + printf("t"); + comma = 1; + } + } + else + printf("none"); + printf("\n"); +} + +static void +print_info(struct cfg *cfg) +{ + const char *c; + int i; + + c = strrchr(cfg->controlfile, '/'); + if (c != NULL) + c = c + 1; + else + c = cfg->controlfile; + if (cfg->verbose) + printf("%s: %s with %d ports and %d VLAN groups\n", + c, cfg->info.es_name, cfg->info.es_nports, cfg->info.es_nvlangroups); + for (i=0; iinfo.es_nports; i++) { + print_port(cfg, i); + } + for (i=0; iinfo.es_nvlangroups; i++) { + print_vlangroup(cfg, i); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: etherswitchctl\n"); + exit(EX_USAGE); +} + +static void +newmode(struct cfg *cfg, enum cmdmode mode) +{ + if (mode == cfg->mode) + return; + switch (cfg->mode) { + case MODE_NONE: + break; + case MODE_PORT: + print_port(cfg, cfg->unit); + break; + case MODE_VLANGROUP: + print_vlangroup(cfg, cfg->unit); + break; + case MODE_REGISTER: + case MODE_PHYREG: + break; + } + cfg->mode = mode; +} + +int +main(int argc, char *argv[]) +{ + int ch; + struct cfg cfg; + int i; + + bzero(&cfg, sizeof(cfg)); + cfg.controlfile = "/dev/etherswitch0"; + while ((ch = getopt(argc, argv, "f:mv?")) != -1) + switch(ch) { + case 'f': + cfg.controlfile = optarg; + break; + case 'm': + cfg.mediatypes++; + break; + case 'v': + cfg.verbose++; + break; + case '?': + /* FALLTHROUGH */ + default: + usage(); + } + argc -= optind; + argv += optind; + cfg.fd = open(cfg.controlfile, O_RDONLY); + if (cfg.fd < 0) + err(EX_UNAVAILABLE, "Can't open control file: %s", cfg.controlfile); + if (ioctl(cfg.fd, IOETHERSWITCHGETINFO, &cfg.info) != 0) + err(EX_OSERR, "ioctl(IOETHERSWITCHGETINFO)"); + if (argc == 0) { + print_info(&cfg); + return (0); + } + cfg.mode = MODE_NONE; + while (argc > 0) { + switch(cfg.mode) { + case MODE_NONE: + if (strcmp(argv[0], "info") == 0) { + print_info(&cfg); + } else if (sscanf(argv[0], "port%d", &cfg.unit) == 1) { + if (cfg.unit < 0 || cfg.unit >= cfg.info.es_nports) + errx(EX_USAGE, "port unit must be between 0 and %d", cfg.info.es_nports); + newmode(&cfg, MODE_PORT); + } else if (sscanf(argv[0], "vlangroup%d", &cfg.unit) == 1) { + if (cfg.unit < 0 || cfg.unit >= cfg.info.es_nvlangroups) + errx(EX_USAGE, "port unit must be between 0 and %d", cfg.info.es_nvlangroups); + newmode(&cfg, MODE_VLANGROUP); + } else if (strcmp(argv[0], "phy") == 0) { + newmode(&cfg, MODE_PHYREG); + } else if (strcmp(argv[0], "reg") == 0) { + newmode(&cfg, MODE_REGISTER); + } else { + errx(EX_USAGE, "Unknown command \"%s\"", argv[0]); + } + break; + case MODE_PORT: + case MODE_VLANGROUP: + for(i=0; cmds[i].name != NULL; i++) { + if (cfg.mode == cmds[i].mode && strcmp(argv[0], cmds[i].name) == 0 + && argc >= cmds[i].args) { + (cmds[i].f)(&cfg, argv); + argc -= cmds[i].args; + argv += cmds[i].args; + break; + } + } + if (cmds[i].name == NULL) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + case MODE_REGISTER: + if (set_register(&cfg, argv[0]) != 0) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + case MODE_PHYREG: + if (set_phyregister(&cfg, argv[0]) != 0) { + newmode(&cfg, MODE_NONE); + continue; + } + break; + } + argc--; + argv++; + } + /* switch back to command mode to print configuration for last command */ + newmode(&cfg, MODE_NONE); + close(cfg.fd); + return (0); +} + +struct cmds cmds[] = { + { MODE_PORT, "vlangroup", 1, set_port_vlangroup }, + { MODE_PORT, "media", 1, set_port_media }, + { MODE_PORT, "mediaopt", 1, set_port_mediaopt }, + { MODE_VLANGROUP, "vlan", 1, set_vlangroup_vid }, + { MODE_VLANGROUP, "members", 1, set_vlangroup_members }, + { 0, NULL, 0, NULL } +}; diff --git a/sbin/etherswitchcfg/ifmedia.c b/sbin/etherswitchcfg/ifmedia.c new file mode 100644 index 0000000..49881fe --- /dev/null +++ b/sbin/etherswitchcfg/ifmedia.c @@ -0,0 +1,812 @@ +/* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */ +/* $FreeBSD: head/sbin/ifconfig/ifmedia.c 221954 2011-05-15 12:51:00Z marius $ */ + +/* + * Copyright (c) 1997 Jason R. Thorpe. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Jason R. Thorpe. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ +/* + * based on sbin/ifconfig/ifmedia.c r221954 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +void domediaopt(const char *, int, int); +int get_media_subtype(int, const char *); +int get_media_mode(int, const char *); +int get_media_options(int, const char *); +int lookup_media_word(struct ifmedia_description *, const char *); +void print_media_word(int, int); +void print_media_word_ifconfig(int); + +#if 0 +static struct ifmedia_description *get_toptype_desc(int); +static struct ifmedia_type_to_subtype *get_toptype_ttos(int); +static struct ifmedia_description *get_subtype_desc(int, + struct ifmedia_type_to_subtype *ttos); + +#define IFM_OPMODE(x) \ + ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \ + IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \ + IFM_IEEE80211_MBSS)) +#define IFM_IEEE80211_STA 0 + +static void +media_status(int s) +{ + struct ifmediareq ifmr; + int *media_list, i; + + (void) memset(&ifmr, 0, sizeof(ifmr)); + (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + /* + * Interface doesn't support SIOC{G,S}IFMEDIA. + */ + return; + } + + if (ifmr.ifm_count == 0) { + warnx("%s: no media types?", name); + return; + } + + media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); + if (media_list == NULL) + err(1, "malloc"); + ifmr.ifm_ulist = media_list; + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + + printf("\tmedia: "); + print_media_word(ifmr.ifm_current, 1); + if (ifmr.ifm_active != ifmr.ifm_current) { + putchar(' '); + putchar('('); + print_media_word(ifmr.ifm_active, 0); + putchar(')'); + } + + putchar('\n'); + + if (ifmr.ifm_status & IFM_AVALID) { + printf("\tstatus: "); + switch (IFM_TYPE(ifmr.ifm_active)) { + case IFM_ETHER: + case IFM_ATM: + if (ifmr.ifm_status & IFM_ACTIVE) + printf("active"); + else + printf("no carrier"); + break; + + case IFM_FDDI: + case IFM_TOKEN: + if (ifmr.ifm_status & IFM_ACTIVE) + printf("inserted"); + else + printf("no ring"); + break; + + case IFM_IEEE80211: + if (ifmr.ifm_status & IFM_ACTIVE) { + /* NB: only sta mode associates */ + if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) + printf("associated"); + else + printf("running"); + } else + printf("no carrier"); + break; + } + putchar('\n'); + } + + if (ifmr.ifm_count > 0 && supmedia) { + printf("\tsupported media:\n"); + for (i = 0; i < ifmr.ifm_count; i++) { + printf("\t\t"); + print_media_word_ifconfig(media_list[i]); + putchar('\n'); + } + } + + free(media_list); +} + +struct ifmediareq * +ifmedia_getstate(int s) +{ + static struct ifmediareq *ifmr = NULL; + int *mwords; + + if (ifmr == NULL) { + ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); + if (ifmr == NULL) + err(1, "malloc"); + + (void) memset(ifmr, 0, sizeof(struct ifmediareq)); + (void) strncpy(ifmr->ifm_name, name, + sizeof(ifmr->ifm_name)); + + ifmr->ifm_count = 0; + ifmr->ifm_ulist = NULL; + + /* + * We must go through the motions of reading all + * supported media because we need to know both + * the current media type and the top-level type. + */ + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { + err(1, "SIOCGIFMEDIA"); + } + + if (ifmr->ifm_count == 0) + errx(1, "%s: no media types?", name); + + mwords = (int *)malloc(ifmr->ifm_count * sizeof(int)); + if (mwords == NULL) + err(1, "malloc"); + + ifmr->ifm_ulist = mwords; + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } + + return ifmr; +} + +static void +setifmediacallback(int s, void *arg) +{ + struct ifmediareq *ifmr = (struct ifmediareq *)arg; + static int did_it = 0; + + if (!did_it) { + ifr.ifr_media = ifmr->ifm_current; + if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) + err(1, "SIOCSIFMEDIA (media)"); + free(ifmr->ifm_ulist); + free(ifmr); + did_it = 1; + } +} + +static void +setmedia(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int subtype; + + ifmr = ifmedia_getstate(s); + + /* + * We are primarily concerned with the top-level type. + * However, "current" may be only IFM_NONE, so we just look + * for the top-level type in the first "supported type" + * entry. + * + * (I'm assuming that all supported media types for a given + * interface will be the same top-level type..) + */ + subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) | + IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediaopt(const char *val, int d, int s, const struct afswtch *afp) +{ + + domediaopt(val, 0, s); +} + +static void +unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp) +{ + + domediaopt(val, 1, s); +} + +static void +domediaopt(const char *val, int clear, int s) +{ + struct ifmediareq *ifmr; + int options; + + ifmr = ifmedia_getstate(s); + + options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = ifmr->ifm_current; + if (clear) + ifr.ifr_media &= ~options; + else { + if (options & IFM_HDX) { + ifr.ifr_media &= ~IFM_FDX; + options &= ~IFM_HDX; + } + ifr.ifr_media |= options; + } + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediainst(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int inst; + + ifmr = ifmedia_getstate(s); + + inst = atoi(val); + if (inst < 0 || inst > (int)IFM_INST_MAX) + errx(1, "invalid media instance: %s", val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} + +static void +setmediamode(const char *val, int d, int s, const struct afswtch *afp) +{ + struct ifmediareq *ifmr; + int mode; + + ifmr = ifmedia_getstate(s); + + mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; + + ifmr->ifm_current = ifr.ifr_media; + callback_register(setifmediacallback, (void *)ifmr); +} +#endif + +/********************************************************************** + * A good chunk of this is duplicated from sys/net/ifmedia.c + **********************************************************************/ + +static struct ifmedia_description ifm_type_descriptions[] = + IFM_TYPE_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_descriptions[] = + IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ethernet_aliases[] = + IFM_SUBTYPE_ETHERNET_ALIASES; + +static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] = + IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_tokenring_descriptions[] = + IFM_SUBTYPE_TOKENRING_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_tokenring_aliases[] = + IFM_SUBTYPE_TOKENRING_ALIASES; + +static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] = + IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_fddi_descriptions[] = + IFM_SUBTYPE_FDDI_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_fddi_aliases[] = + IFM_SUBTYPE_FDDI_ALIASES; + +static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] = + IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] = + IFM_SUBTYPE_IEEE80211_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_ieee80211_aliases[] = + IFM_SUBTYPE_IEEE80211_ALIASES; + +static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] = + IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS; + +struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] = + IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS; + +struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] = + IFM_SUBTYPE_IEEE80211_MODE_ALIASES; + +static struct ifmedia_description ifm_subtype_atm_descriptions[] = + IFM_SUBTYPE_ATM_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_atm_aliases[] = + IFM_SUBTYPE_ATM_ALIASES; + +static struct ifmedia_description ifm_subtype_atm_option_descriptions[] = + IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_shared_descriptions[] = + IFM_SUBTYPE_SHARED_DESCRIPTIONS; + +static struct ifmedia_description ifm_subtype_shared_aliases[] = + IFM_SUBTYPE_SHARED_ALIASES; + +static struct ifmedia_description ifm_shared_option_descriptions[] = + IFM_SHARED_OPTION_DESCRIPTIONS; + +static struct ifmedia_description ifm_shared_option_aliases[] = + IFM_SHARED_OPTION_ALIASES; + +struct ifmedia_type_to_subtype { + struct { + struct ifmedia_description *desc; + int alias; + } subtypes[5]; + struct { + struct ifmedia_description *desc; + int alias; + } options[4]; + struct { + struct ifmedia_description *desc; + int alias; + } modes[3]; +}; + +/* must be in the same order as IFM_TYPE_DESCRIPTIONS */ +static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = { + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_ethernet_descriptions[0], 0 }, + { &ifm_subtype_ethernet_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_ethernet_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_tokenring_descriptions[0], 0 }, + { &ifm_subtype_tokenring_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_tokenring_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_fddi_descriptions[0], 0 }, + { &ifm_subtype_fddi_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_fddi_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_ieee80211_descriptions[0], 0 }, + { &ifm_subtype_ieee80211_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_ieee80211_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { &ifm_subtype_ieee80211_mode_descriptions[0], 0 }, + { &ifm_subtype_ieee80211_mode_aliases[0], 0 }, + { NULL, 0 }, + }, + }, + { + { + { &ifm_subtype_shared_descriptions[0], 0 }, + { &ifm_subtype_shared_aliases[0], 1 }, + { &ifm_subtype_atm_descriptions[0], 0 }, + { &ifm_subtype_atm_aliases[0], 1 }, + { NULL, 0 }, + }, + { + { &ifm_shared_option_descriptions[0], 0 }, + { &ifm_shared_option_aliases[0], 1 }, + { &ifm_subtype_atm_option_descriptions[0], 0 }, + { NULL, 0 }, + }, + { + { NULL, 0 }, + }, + }, +}; + +int +get_media_subtype(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int rval, i; + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media type 0x%x", type); + + for (i = 0; ttos->subtypes[i].desc != NULL; i++) { + rval = lookup_media_word(ttos->subtypes[i].desc, val); + if (rval != -1) + return (rval); + } + errx(1, "unknown media subtype: %s", val); + /*NOTREACHED*/ +} + +int +get_media_mode(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int rval, i; + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media mode 0x%x", type); + + for (i = 0; ttos->modes[i].desc != NULL; i++) { + rval = lookup_media_word(ttos->modes[i].desc, val); + if (rval != -1) + return (rval); + } + return -1; +} + +int +get_media_options(int type, const char *val) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + char *optlist, *optptr; + int option = 0, i, rval = 0; + + /* We muck with the string, so copy it. */ + optlist = strdup(val); + if (optlist == NULL) + err(1, "strdup"); + + /* Find the top-level interface type. */ + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (type == desc->ifmt_word) + break; + if (desc->ifmt_string == NULL) + errx(1, "unknown media type 0x%x", type); + + /* + * Look up the options in the user-provided comma-separated + * list. + */ + optptr = optlist; + for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) { + for (i = 0; ttos->options[i].desc != NULL; i++) { + option = lookup_media_word(ttos->options[i].desc, optptr); + if (option != -1) + break; + } + if (option == 0) + errx(1, "unknown option: %s", optptr); + rval |= option; + } + + free(optlist); + return (rval); +} + +int +lookup_media_word(struct ifmedia_description *desc, const char *val) +{ + + for (; desc->ifmt_string != NULL; desc++) + if (strcasecmp(desc->ifmt_string, val) == 0) + return (desc->ifmt_word); + + return (-1); +} + +static struct ifmedia_description *get_toptype_desc(int ifmw) +{ + struct ifmedia_description *desc; + + for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) + if (IFM_TYPE(ifmw) == desc->ifmt_word) + break; + + return desc; +} + +static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + + for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; + desc->ifmt_string != NULL; desc++, ttos++) + if (IFM_TYPE(ifmw) == desc->ifmt_word) + break; + + return ttos; +} + +static struct ifmedia_description *get_subtype_desc(int ifmw, + struct ifmedia_type_to_subtype *ttos) +{ + int i; + struct ifmedia_description *desc; + + for (i = 0; ttos->subtypes[i].desc != NULL; i++) { + if (ttos->subtypes[i].alias) + continue; + for (desc = ttos->subtypes[i].desc; + desc->ifmt_string != NULL; desc++) { + if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) + return desc; + } + } + + return NULL; +} + +static struct ifmedia_description *get_mode_desc(int ifmw, + struct ifmedia_type_to_subtype *ttos) +{ + int i; + struct ifmedia_description *desc; + + for (i = 0; ttos->modes[i].desc != NULL; i++) { + if (ttos->modes[i].alias) + continue; + for (desc = ttos->modes[i].desc; + desc->ifmt_string != NULL; desc++) { + if (IFM_MODE(ifmw) == desc->ifmt_word) + return desc; + } + } + + return NULL; +} + +void +print_media_word(int ifmw, int print_toptype) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int seen_option = 0, i; + + /* Find the top-level interface type. */ + desc = get_toptype_desc(ifmw); + ttos = get_toptype_ttos(ifmw); + if (desc->ifmt_string == NULL) { + printf(""); + return; + } else if (print_toptype) { + printf("%s", desc->ifmt_string); + } + + /* + * Don't print the top-level type; it's not like we can + * change it, or anything. + */ + + /* Find subtype. */ + desc = get_subtype_desc(ifmw, ttos); + if (desc == NULL) { + printf(""); + return; + } + + if (print_toptype) + putchar(' '); + + printf("%s", desc->ifmt_string); + + if (print_toptype) { + desc = get_mode_desc(ifmw, ttos); + if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string)) + printf(" mode %s", desc->ifmt_string); + } + + /* Find options. */ + for (i = 0; ttos->options[i].desc != NULL; i++) { + if (ttos->options[i].alias) + continue; + for (desc = ttos->options[i].desc; + desc->ifmt_string != NULL; desc++) { + if (ifmw & desc->ifmt_word) { + if (seen_option == 0) + printf(" <"); + printf("%s%s", seen_option++ ? "," : "", + desc->ifmt_string); + } + } + } + printf("%s", seen_option ? ">" : ""); + + if (print_toptype && IFM_INST(ifmw) != 0) + printf(" instance %d", IFM_INST(ifmw)); +} + +void +print_media_word_ifconfig(int ifmw) +{ + struct ifmedia_description *desc; + struct ifmedia_type_to_subtype *ttos; + int seen_option = 0, i; + + /* Find the top-level interface type. */ + desc = get_toptype_desc(ifmw); + ttos = get_toptype_ttos(ifmw); + if (desc->ifmt_string == NULL) { + printf(""); + return; + } + + /* + * Don't print the top-level type; it's not like we can + * change it, or anything. + */ + + /* Find subtype. */ + desc = get_subtype_desc(ifmw, ttos); + if (desc == NULL) { + printf(""); + return; + } + + printf("media %s", desc->ifmt_string); + + desc = get_mode_desc(ifmw, ttos); + if (desc != NULL) + printf(" mode %s", desc->ifmt_string); + + /* Find options. */ + for (i = 0; ttos->options[i].desc != NULL; i++) { + if (ttos->options[i].alias) + continue; + for (desc = ttos->options[i].desc; + desc->ifmt_string != NULL; desc++) { + if (ifmw & desc->ifmt_word) { + if (seen_option == 0) + printf(" mediaopt "); + printf("%s%s", seen_option++ ? "," : "", + desc->ifmt_string); + } + } + } + + if (IFM_INST(ifmw) != 0) + printf(" instance %d", IFM_INST(ifmw)); +} + +/********************************************************************** + * ...until here. + **********************************************************************/ diff --git a/sys/conf/files b/sys/conf/files index 2f8b5f6..ace37f3 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3523,3 +3523,11 @@ dev/xen/control/control.c optional xen | xenhvm dev/xen/netfront/netfront.c optional xen | xenhvm dev/xen/xenpci/xenpci.c optional xenpci dev/xen/xenpci/evtchn.c optional xenpci + +dev/etherswitch/arswitch.c optional arswitch +dev/etherswitch/etherswitch.c optional etherswitch +dev/etherswitch/etherswitch_if.m optional etherswitch +dev/etherswitch/mdio_if.m optional miiproxy +dev/etherswitch/mdio.c optional miiproxy +dev/etherswitch/miiproxy.c optional miiproxy +dev/etherswitch/rtl8366rb.c optional rtl8366rb diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 7bf7643..182a687 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -352,7 +352,8 @@ MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m \ kern/bus_if.m kern/clock_if.m \ kern/cpufreq_if.m kern/device_if.m kern/serdev_if.m \ libkern/iconv_converter_if.m opencrypto/cryptodev_if.m \ - pc98/pc98/canbus_if.m + pc98/pc98/canbus_if.m dev/etherswitch/etherswitch_if.m \ + dev/etherswitch/mdio_if.h .for _srcsrc in ${MFILES} .for _ext in c h diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 0384283..5a03c80 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -70,7 +70,8 @@ OCTEON_BOARD_CAPK_0100ND opt_cvmx.h # # Options that control the Atheros SoC peripherals # -ARGE_DEBUG opt_global.h +ARGE_DEBUG opt_arge.h +ARGE_MDIO opt_arge.h # # Options that control the Ralink RT305xF Etherenet MAC. diff --git a/sys/dev/etherswitch/arswitch.c b/sys/dev/etherswitch/arswitch.c new file mode 100644 index 0000000..460e42b --- /dev/null +++ b/sys/dev/etherswitch/arswitch.c @@ -0,0 +1,675 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mdio_if.h" +#include "miibus_if.h" +#include "etherswitch_if.h" + + +struct arswitch_softc { + struct mtx sc_mtx; /* serialize access to softc */ + device_t dev; + int phy4cpu; /* PHY4 is connected to the CPU */ + int numphys; /* PHYs we manage */ + int page; + char *ifname[AR8X16_NUM_PHYS]; + device_t miibus[AR8X16_NUM_PHYS]; + struct ifnet *ifp[AR8X16_NUM_PHYS]; + struct callout callout_tick; + etherswitch_info_t info; +}; + + + +#define ARSWITCH_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define ARSWITCH_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define ARSWITCH_LOCK_ASSERT(_sc, _what) mtx_assert(&(_s)c->sc_mtx, (_what)) +#define ARSWITCH_TRYLOCK(_sc) mtx_trylock(&(_sc)->sc_mtx) + + +#if defined(DEBUG) +#define DPRINTF(dev, args...) device_printf(dev, args) +#define DEVERR(dev, err, fmt, args...) do { \ + if (err != 0) device_printf(dev, fmt, err, args); \ + } while (0) +#define DEBUG_INCRVAR(var) do { \ + var++; \ + } while (0) + +static SYSCTL_NODE(_debug, OID_AUTO, arswitch, CTLFLAG_RD, 0, "arswitch"); +#else +#define DPRINTF(dev, args...) +#define DEVERR(dev, err, fmt, args...) +#define DEBUG_INCRVAR(var) +#endif + +static inline int arswitch_portforphy(int phy); +static void arswitch_tick(void *arg); +static int arswitch_ifmedia_upd(struct ifnet *); +static void arswitch_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static int arswitch_readreg(device_t dev, int addr); +static int arswitch_writereg(device_t dev, int addr, int value); +int arswitch_modifyreg(device_t dev, int addr, int mask, int set); + +static void +arswitch_identify(driver_t *driver, device_t parent) +{ + device_t child; + + if (device_find_child(parent, driver->name, -1) == NULL) { + child = BUS_ADD_CHILD(parent, 0, driver->name, -1); + } +} + +static int +arswitch_probe(device_t dev) +{ + struct arswitch_softc *sc; + uint32_t id; + char *chipname, desc[256]; + + sc = device_get_softc(dev); + bzero(sc, sizeof(*sc)); + sc->page = -1; + id = arswitch_readreg(dev, AR8X16_REG_MASK_CTRL); + switch ((id & AR8X16_MASK_CTRL_VER_MASK) >> AR8X16_MASK_CTRL_VER_SHIFT) { + case 1: + chipname = "AR8216"; + break; + case 2: + chipname = "AR8226"; + break; + case 16: + chipname = "AR8316"; + break; + default: + chipname = NULL; + } + DPRINTF(dev, "chipname=%s, rev=%02x\n", chipname, id & AR8X16_MASK_CTRL_REV_MASK); + if (chipname != NULL) { + snprintf(desc, sizeof(desc), "Atheros %s Ethernet Switch", chipname); + device_set_desc_copy(dev, desc); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static int +arswitch_attach_phys(struct arswitch_softc *sc) +{ + int phy, err = 0; + char name[IFNAMSIZ]; + + /* PHYs need an interface, so we generate a dummy one */ + snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->dev)); + for (phy = 0; phy < sc->numphys; phy++) { + sc->ifp[phy] = if_alloc(IFT_ETHER); + sc->ifp[phy]->if_softc = sc; + sc->ifp[phy]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING + | IFF_SIMPLEX; + sc->ifname[phy] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK); + bcopy(name, sc->ifname[phy], strlen(name)+1); + if_initname(sc->ifp[phy], sc->ifname[phy], arswitch_portforphy(phy)); + err = mii_attach(sc->dev, &sc->miibus[phy], sc->ifp[phy], + arswitch_ifmedia_upd, arswitch_ifmedia_sts, \ + BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + DPRINTF(sc->dev, "%s attached to pseudo interface %s\n", + device_get_nameunit(sc->miibus[phy]), sc->ifp[phy]->if_xname); + if (err != 0) { + device_printf(sc->dev, "attaching PHY %d failed\n", phy); + } + } + return (err); +} + +static int +arswitch_attach(device_t dev) +{ + struct arswitch_softc *sc; + int err = 0; + + sc = device_get_softc(dev); + bzero(sc, sizeof(*sc)); + sc->dev = dev; + mtx_init(&sc->sc_mtx, "arswitch", NULL, MTX_DEF); + sc->page = -1; + + sc->info.es_nports = 5; /* XXX technically 6, but 6th not used */ + sc->info.es_nvlangroups = 16; + strlcpy(sc->info.es_name, device_get_desc(dev), sizeof(sc->info.es_name)); + + /* XXX make this configurable */ + sc->numphys = 4; + sc->phy4cpu = 1; + +#ifdef NOTYET + arswitch_writereg(dev, AR8X16_REG_MASK_CTRL, AR8X16_MASK_CTRL_SOFT_RESET); + DELAY(1000); + if (arswitch_readreg(dev, AR8X16_REG_MASK_CTRL) & AR8X16_MASK_CTRL_SOFT_RESET) { + device_printf(dev, "unable to reset switch\n"); + return (ENXIO); + } + arswitch_modifyreg(dev, AR8X16_REG_GLOBAL_CTRL, + AR8X16_FLOOD_MASK_BCAST_TO_CPU, + AR8X16_FLOOD_MASK_BCAST_TO_CPU); +#endif + err = arswitch_attach_phys(sc); + if (err != 0) + return (err); + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + err = bus_generic_attach(dev); + if (err != 0) + return (err); + + callout_init_mtx(&sc->callout_tick, &sc->sc_mtx, 0); + arswitch_tick(sc); + + return (err); +} + +static int +arswitch_detach(device_t dev) +{ + struct arswitch_softc *sc = device_get_softc(dev); + int i; + + callout_drain(&sc->callout_tick); + + for (i=0; i < sc->numphys; i++) { + if (sc->miibus[i] != NULL) + device_delete_child(dev, sc->miibus[i]); + if (sc->ifp[i] != NULL) + if_free(sc->ifp[i]); + free(sc->ifname[i], M_DEVBUF); + } + + bus_generic_detach(dev); + mtx_destroy(&sc->sc_mtx); + + return (0); +} + +/* + * Convert PHY number to port number. PHY0 is connected to port 1, PHY1 to + * port 2, etc. + */ +static inline int +arswitch_portforphy(int phy) +{ + return (phy+1); +} + +static inline struct mii_data * +arswitch_miiforport(struct arswitch_softc *sc, int port) +{ + int phy = port-1; + + if (phy < 0 || phy >= sc->numphys) + return (NULL); + return (device_get_softc(sc->miibus[phy])); +} + +/* + * Convert port status to ifmedia. + */ +static void +arswitch_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active) +{ + *media_active = IFM_ETHER; + *media_status = IFM_AVALID; + + if ((portstatus & AR8X16_PORT_STS_LINK_UP) != 0) + *media_status |= IFM_ACTIVE; + else { + *media_active |= IFM_NONE; + return; + } + switch (portstatus & AR8X16_PORT_STS_SPEED_MASK) { + case AR8X16_PORT_STS_SPEED_10: + *media_active |= IFM_10_T; + break; + case AR8X16_PORT_STS_SPEED_100: + *media_active |= IFM_100_TX; + break; + case AR8X16_PORT_STS_SPEED_1000: + *media_active |= IFM_1000_T; + break; + } + if ((portstatus & AR8X16_PORT_STS_DUPLEX) == 0) + *media_active |= IFM_FDX; + else + *media_active |= IFM_HDX; + if ((portstatus & AR8X16_PORT_STS_TXFLOW) != 0) + *media_active |= IFM_ETH_TXPAUSE; + if ((portstatus & AR8X16_PORT_STS_RXFLOW) != 0) + *media_active |= IFM_ETH_RXPAUSE; +} + +/* + * Poll the status for all PHYs. We're using the switch port status because + * thats a lot quicker to read than talking to all the PHYs. Care must be + * taken that the resulting ifmedia_active is identical to what the PHY will + * compute, or gratuitous link status changes will occur whenever the PHYs + * update function is called. + */ +static void +arswitch_miipollstat(struct arswitch_softc *sc) +{ + int i; + struct mii_data *mii; + struct mii_softc *miisc; + int portstatus; + + for (i = 0; i < sc->numphys; i++) { + if (sc->miibus[i] == NULL) + continue; + mii = device_get_softc(sc->miibus[i]); + portstatus = arswitch_readreg(sc->dev, + AR8X16_REG_PORT_STS(arswitch_portforphy(i))); + //DPRINTF(sc->dev, "p[%d]=%b\n", arge_portforphy(i), portstatus, + // "\20\3TXMAC\4RXMAC\5TXFLOW\6RXFLOW\7DUPLEX\11LINK_UP\12LINK_AUTO\13LINK_PAUSE"); + arswitch_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active); + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { + if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst) + continue; + mii_phy_update(miisc, MII_POLLSTAT); + } + } +} + +static void +arswitch_tick(void *arg) +{ + struct arswitch_softc *sc = arg; + + arswitch_miipollstat(sc); + callout_reset(&sc->callout_tick, hz, arswitch_tick, sc); +} + +static etherswitch_info_t * +arswitch_getinfo(device_t dev) +{ + struct arswitch_softc *sc = device_get_softc(dev); + + return (&sc->info); +} + +static inline void +arswitch_split_setpage(device_t dev, uint32_t addr, uint16_t *phy, uint16_t *reg) +{ + struct arswitch_softc *sc = device_get_softc(dev); + uint16_t page; + + page = ((addr) >> 9) & 0xffff; + *phy = (((addr) >> 6) & 0x07) | 0x10; + *reg = ((addr) >> 1) & 0x1f; + + if (sc->page != page) { + MDIO_WRITEREG(device_get_parent(dev), 0x18, 0, page); + sc->page = page; + } +} + +/* + * Read half a register. Some of the registers define control bits, and + * the sequence of half-word accesses matters. The register addresses + * are word-even (mod 4). + */ +static inline int +arswitch_readreg16(device_t dev, int addr) +{ + uint16_t phy, reg; + + arswitch_split_setpage(dev, addr, &phy, ®); + return (MDIO_READREG(device_get_parent(dev), phy, reg)); +} + +/* + * Write half a register + */ +static inline int +arswitch_writereg16(device_t dev, int addr, int data) +{ + uint16_t phy, reg; + + arswitch_split_setpage(dev, addr, &phy, ®); + return (MDIO_WRITEREG(device_get_parent(dev), phy, reg, data)); +} + +static inline int +arswitch_readreg_lsb(device_t dev, int addr) +{ + return (arswitch_readreg16(dev, addr)); +} + +static inline int +arswitch_readreg_msb(device_t dev, int addr) +{ + return (arswitch_readreg16(dev, addr + 2) << 16); +} + +static inline int +arswitch_writereg_lsb(device_t dev, int addr, int data) +{ + return (arswitch_writereg16(dev, addr, data & 0xffff)); +} + +static inline int +arswitch_writereg_msb(device_t dev, int addr, int data) +{ + return (arswitch_writereg16(dev, addr + 2, data >> 16)); +} + +static int +arswitch_readreg(device_t dev, int addr) +{ + return (arswitch_readreg_lsb(dev, addr) | arswitch_readreg_msb(dev, addr)); +} + +static int +arswitch_writereg(device_t dev, int addr, int value) +{ + arswitch_writereg_lsb(dev, addr, value); + return (arswitch_writereg_msb(dev, addr, value)); +} + +int +arswitch_modifyreg(device_t dev, int addr, int mask, int set) +{ + int value; + + value = arswitch_readreg(dev, addr); + value &= ~mask; + value |= set; + return arswitch_writereg(dev, addr, value); +} + +static int +arswitch_getport(device_t dev, etherswitch_port_t *p) +{ + struct arswitch_softc *sc = device_get_softc(dev); + struct mii_data *mii; + struct ifmediareq *ifmr = &p->es_ifmr; + int err; + + if (p->es_port < 0 || p->es_port >= AR8X16_NUM_PORTS) + return (ENXIO); + p->es_vlangroup = 0; + + mii = arswitch_miiforport(sc, p->es_port); + if (p->es_port == 0) { + /* fill in fixed values for CPU port */ + ifmr->ifm_count = 0; + ifmr->ifm_current = ifmr->ifm_active = + IFM_ETHER | IFM_1000_T | IFM_FDX; + ifmr->ifm_mask = 0; + ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; + } else if (mii != NULL) { + err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, + &mii->mii_media, SIOCGIFMEDIA); + if (err) + return (err); + } else { + return (ENXIO); + } + return (0); +} + +static int +arswitch_setport(device_t dev, etherswitch_port_t *p) +{ +#if 0 + int err; + struct arswitch_softc *sc; + struct ifmedia *ifm; + struct mii_data *mii; + + if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS) + return (ENXIO); + err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port), + RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK), + RTL8366RB_PVCR_VAL(p->es_port, p->es_vlangroup), ARSWITCH_WAITOK); + if (err) + return (err); + sc = device_get_softc(dev); + mii = device_get_softc(sc->miibus[p->es_port]); + ifm = &mii->mii_media; + err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA); + return (err); +#else + return (0); +#endif +} + +static int +arswitch_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ +#if 0 + uint16_t vmcr[3]; + int i; + + for (i=0; i<3; i++) + vmcr[i] = arswitch_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup)); +#endif + + vg->es_vid = 0; + vg->es_member_ports = 0; + vg->es_untagged_ports = 0; + vg->es_fid = 0; + return (0); +} + +static int +arswitch_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ +#if 0 + int g = vg->es_vlangroup; + + arswitch_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g), + (vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK); + arswitch_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g), + ((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) | + ((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK)); + arswitch_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g), + vg->es_fid); +#endif + return (0); +} + +/* + * access PHYs integrated into the switch chip through the switch's MDIO + * control register. + */ +static int +arswitch_readphy(device_t dev, int phy, int reg) +{ + uint32_t data = 0, ctrl; + int err, timeout; + + if (phy < 0 || phy >= 32) + return (ENXIO); + if (reg < 0 || reg >= 32) + return (ENXIO); + err = arswitch_writereg_msb(dev, AR8X16_REG_MDIO_CTRL, + AR8X16_MDIO_CTRL_BUSY | AR8X16_MDIO_CTRL_MASTER_EN | + AR8X16_MDIO_CTRL_CMD_READ | + (phy << AR8X16_MDIO_CTRL_PHY_ADDR_SHIFT) | + (reg << AR8X16_MDIO_CTRL_REG_ADDR_SHIFT)); + DEVERR(dev, err, "arswitch_readphy()=%d: phy=%d.%02x\n", phy, reg); + if (err != 0) + return (-1); + for (timeout = 100; timeout--; ) { + ctrl = arswitch_readreg_msb(dev, AR8X16_REG_MDIO_CTRL); + if ((ctrl & AR8X16_MDIO_CTRL_BUSY) == 0) + break; + } + if (timeout < 0) + err = EIO; + data = arswitch_readreg_lsb(dev, AR8X16_REG_MDIO_CTRL) & AR8X16_MDIO_CTRL_DATA_MASK; + return (data); +} + +static int +arswitch_writephy(device_t dev, int phy, int reg, int data) +{ + uint32_t ctrl; + int err, timeout; + + if (reg < 0 || reg >= 32) + return (ENXIO); + err = arswitch_writereg_lsb(dev, AR8X16_REG_MDIO_CTRL, + (data & AR8X16_MDIO_CTRL_DATA_MASK)); + DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); + if (err != 0) + return (err); + err = arswitch_writereg_msb(dev, AR8X16_REG_MDIO_CTRL, + AR8X16_MDIO_CTRL_BUSY | + AR8X16_MDIO_CTRL_MASTER_EN | + AR8X16_MDIO_CTRL_CMD_WRITE | + (phy << AR8X16_MDIO_CTRL_PHY_ADDR_SHIFT) | + (reg << AR8X16_MDIO_CTRL_REG_ADDR_SHIFT)); + DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); + if (err != 0) + return (err); + for (timeout = 100; timeout--; ) { + ctrl = arswitch_readreg(dev, AR8X16_REG_MDIO_CTRL); + if ((ctrl & AR8X16_MDIO_CTRL_BUSY) == 0) + break; + } + if (timeout < 0) + err = EIO; + DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); + return (err); +} + +static void +arswitch_statchg(device_t dev) +{ + device_printf(dev, "%s\n", __func__); +} + +static int +arswitch_ifmedia_upd(struct ifnet *ifp) +{ + struct arswitch_softc *sc = ifp->if_softc; + struct mii_data *mii = arswitch_miiforport(sc, ifp->if_dunit); + + if (mii == NULL) + return (ENXIO); + mii_mediachg(mii); + return (0); +} + +static void +arswitch_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct arswitch_softc *sc = ifp->if_softc; + struct mii_data *mii = arswitch_miiforport(sc, ifp->if_dunit); + + device_printf(sc->dev, "%s\n", __func__); + if (mii == NULL) + return; + mii_pollstat(mii); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +static device_method_t arswitch_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, arswitch_identify), + DEVMETHOD(device_probe, arswitch_probe), + DEVMETHOD(device_attach, arswitch_attach), + DEVMETHOD(device_detach, arswitch_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + + /* MII interface */ + DEVMETHOD(miibus_readreg, arswitch_readphy), + DEVMETHOD(miibus_writereg, arswitch_writephy), + DEVMETHOD(miibus_statchg, arswitch_statchg), + + /* MDIO interface */ + DEVMETHOD(mdio_readreg, arswitch_readphy), + DEVMETHOD(mdio_writereg, arswitch_writephy), + + /* etherswitch interface */ + DEVMETHOD(etherswitch_getinfo, arswitch_getinfo), + DEVMETHOD(etherswitch_readreg, arswitch_readreg), + DEVMETHOD(etherswitch_writereg, arswitch_writereg), + DEVMETHOD(etherswitch_readphyreg, arswitch_readphy), + DEVMETHOD(etherswitch_writephyreg, arswitch_writephy), + DEVMETHOD(etherswitch_getport, arswitch_getport), + DEVMETHOD(etherswitch_setport, arswitch_setport), + DEVMETHOD(etherswitch_getvgroup, arswitch_getvgroup), + DEVMETHOD(etherswitch_setvgroup, arswitch_setvgroup), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(arswitch, arswitch_driver, arswitch_methods, + sizeof(struct arswitch_softc)); +static devclass_t arswitch_devclass; + +DRIVER_MODULE(arswitch, mdio, arswitch_driver, arswitch_devclass, 0, 0); +DRIVER_MODULE(miibus, arswitch, miibus_driver, miibus_devclass, 0, 0); +DRIVER_MODULE(mdio, arswitch, mdio_driver, mdio_devclass, 0, 0); +DRIVER_MODULE(etherswitch, arswitch, etherswitch_driver, etherswitch_devclass, 0, 0); +MODULE_VERSION(arswitch, 1); +MODULE_DEPEND(arswitch, miibus, 1, 1, 1); /* XXX which versions? */ +MODULE_DEPEND(arswitch, etherswitch, 1, 1, 1); /* XXX which versions? */ diff --git a/sys/dev/etherswitch/arswitchreg.h b/sys/dev/etherswitch/arswitchreg.h new file mode 100644 index 0000000..cd827cf --- /dev/null +++ b/sys/dev/etherswitch/arswitchreg.h @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2011 Aleksandr Rybalko. + * 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 __AR8X16_SWITCHREG_H__ +#define __AR8X16_SWITCHREG_H__ + +#define AR8X16_REG_MASK_CTRL 0x0000 +#define AR8X16_MASK_CTRL_REV_MASK 0x000000ff +#define AR8X16_MASK_CTRL_VER_MASK 0x0000ff00 +#define AR8X16_MASK_CTRL_VER_SHIFT 8 +#define AR8X16_MASK_CTRL_SOFT_RESET (1 << 31) + +#define AR8X16_REG_MODE 0x0008 +/* DIR-615 E4 U-Boot */ +#define AR8X16_MODE_DIR_615_UBOOT 0x8d1003e0 +/* From Ubiquiti RSPRO */ +#define AR8X16_MODE_RGMII_PORT4_ISO 0x81461bea +#define AR8X16_MODE_RGMII_PORT4_SWITCH 0x01261be2 +/* AVM Fritz!Box 7390 */ +#define AR8X16_MODE_GMII 0x010e5b71 +/* from avm_cpmac/linux_ar_reg.h */ +#define AR8X16_MODE_RESERVED 0x000e1b20 +#define AR8X16_MODE_MAC0_GMII_EN (1u << 0) +#define AR8X16_MODE_MAC0_RGMII_EN (1u << 1) +#define AR8X16_MODE_PHY4_GMII_EN (1u << 2) +#define AR8X16_MODE_PHY4_RGMII_EN (1u << 3) +#define AR8X16_MODE_MAC0_MAC_MODE (1u << 4) +#define AR8X16_MODE_RGMII_RXCLK_DELAY_EN (1u << 6) +#define AR8X16_MODE_RGMII_TXCLK_DELAY_EN (1u << 7) +#define AR8X16_MODE_MAC5_MAC_MODE (1u << 14) +#define AR8X16_MODE_MAC5_PHY_MODE (1u << 15) +#define AR8X16_MODE_TXDELAY_S0 (1u << 21) +#define AR8X16_MODE_TXDELAY_S1 (1u << 22) +#define AR8X16_MODE_RXDELAY_S0 (1u << 23) +#define AR8X16_MODE_LED_OPEN_EN (1u << 24) +#define AR8X16_MODE_SPI_EN (1u << 25) +#define AR8X16_MODE_RXDELAY_S1 (1u << 26) +#define AR8X16_MODE_POWER_ON_SEL (1u << 31) + +#define AR8X16_REG_ISR 0x0010 +#define AR8X16_REG_IMR 0x0014 + +#define AR8X16_REG_SW_MAC_ADDR0 0x0020 +#define AR8X16_REG_SW_MAC_ADDR1 0x0024 + +#define AR8X16_REG_FLOOD_MASK 0x002c +#define AR8X16_FLOOD_MASK_BCAST_TO_CPU (1 << 26) + +#define AR8X16_REG_GLOBAL_CTRL 0x0030 +#define AR8X16_GLOBAL_CTRL_MTU_MASK 0x00000fff + +#define AR8X16_REG_VLAN_CTRL 0x0040 +#define AR8X16_VLAN_OP 0x00000007 +#define AR8X16_VLAN_OP_NOOP 0x0 +#define AR8X16_VLAN_OP_FLUSH 0x1 +#define AR8X16_VLAN_OP_LOAD 0x2 +#define AR8X16_VLAN_OP_PURGE 0x3 +#define AR8X16_VLAN_OP_REMOVE_PORT 0x4 +#define AR8X16_VLAN_OP_GET_NEXT 0x5 +#define AR8X16_VLAN_OP_GET 0x6 +#define AR8X16_VLAN_ACTIVE (1 << 3) +#define AR8X16_VLAN_FULL (1 << 4) +#define AR8X16_VLAN_PORT 0x00000f00 +#define AR8X16_VLAN_PORT_SHIFT 8 +#define AR8X16_VLAN_VID 0x0fff0000 +#define AR8X16_VLAN_VID_SHIFT 16 +#define AR8X16_VLAN_PRIO 0x70000000 +#define AR8X16_VLAN_PRIO_SHIFT 28 +#define AR8X16_VLAN_PRIO_EN (1 << 31) + +#define AR8X16_REG_VLAN_DATA 0x0044 +#define AR8X16_VLAN_MEMBER 0x000003ff +#define AR8X16_VLAN_VALID (1 << 11) + +#define AR8X16_REG_ARL_CTRL0 0x0050 +#define AR8X16_REG_ARL_CTRL1 0x0054 +#define AR8X16_REG_ARL_CTRL2 0x0058 + +#define AR8X16_REG_AT_CTRL 0x005c +#define AR8X16_AT_CTRL_ARP_EN (1 << 20) + +#define AR8X16_REG_IP_PRIORITY_1 0x0060 +#define AR8X16_REG_IP_PRIORITY_2 0x0064 +#define AR8X16_REG_IP_PRIORITY_3 0x0068 +#define AR8X16_REG_IP_PRIORITY_4 0x006C + +#define AR8X16_REG_TAG_PRIO 0x0070 + +#define AR8X16_REG_SERVICE_TAG 0x0074 +#define AR8X16_SERVICE_TAG_MASK 0x0000ffff + +#define AR8X16_REG_CPU_PORT 0x0078 +#define AR8X16_MIRROR_PORT_SHIFT 4 +#define AR8X16_CPU_PORT_EN (1 << 8) + +#define AR8X16_REG_MIB_FUNC0 0x0080 +#define AR8X16_MIB_TIMER_MASK 0x0000ffff +#define AR8X16_MIB_AT_HALF_EN (1 << 16) +#define AR8X16_MIB_BUSY (1 << 17) +#define AR8X16_MIB_FUNC_SHIFT 24 +#define AR8X16_MIB_FUNC_NO_OP 0x0 +#define AR8X16_MIB_FUNC_FLUSH 0x1 +#define AR8X16_MIB_FUNC_CAPTURE 0x3 +#define AR8X16_MIB_FUNC_XXX (1 << 30) /* 0x40000000 */ + +#define AR8X16_REG_MDIO_HIGH_ADDR 0x0094 + +#define AR8X16_REG_MDIO_CTRL 0x0098 +#define AR8X16_MDIO_CTRL_DATA_MASK 0x0000ffff +#define AR8X16_MDIO_CTRL_REG_ADDR_SHIFT 16 +#define AR8X16_MDIO_CTRL_PHY_ADDR_SHIFT 21 +#define AR8X16_MDIO_CTRL_CMD_WRITE 0 +#define AR8X16_MDIO_CTRL_CMD_READ (1 << 27) +#define AR8X16_MDIO_CTRL_MASTER_EN (1 << 30) +#define AR8X16_MDIO_CTRL_BUSY (1 << 31) + +#define AR8X16_REG_PORT_BASE(_p) (0x0100 + (_p) * 0x0100) + +#define AR8X16_REG_PORT_STS(_p) (AR8X16_REG_PORT_BASE((_p)) + 0x0000) +#define AR8X16_PORT_STS_SPEED_MASK 0x00000003 +#define AR8X16_PORT_STS_SPEED_10 0 +#define AR8X16_PORT_STS_SPEED_100 1 +#define AR8X16_PORT_STS_SPEED_1000 2 +#define AR8X16_PORT_STS_TXMAC (1 << 2) +#define AR8X16_PORT_STS_RXMAC (1 << 3) +#define AR8X16_PORT_STS_TXFLOW (1 << 4) +#define AR8X16_PORT_STS_RXFLOW (1 << 5) +#define AR8X16_PORT_STS_DUPLEX (1 << 6) +#define AR8X16_PORT_STS_LINK_UP (1 << 8) +#define AR8X16_PORT_STS_LINK_AUTO (1 << 9) +#define AR8X16_PORT_STS_LINK_PAUSE (1 << 10) + +#define AR8X16_REG_PORT_CTRL(_p) (AR8X16_REG_PORT_BASE((_p)) + 0x0004) +#define AR8X16_PORT_CTRL_STATE_MASK 0x00000007 +#define AR8X16_PORT_CTRL_STATE_DISABLED 0 +#define AR8X16_PORT_CTRL_STATE_BLOCK 1 +#define AR8X16_PORT_CTRL_STATE_LISTEN 2 +#define AR8X16_PORT_CTRL_STATE_LEARN 3 +#define AR8X16_PORT_CTRL_STATE_FORWARD 4 +#define AR8X16_PORT_CTRL_LEARN_LOCK (1 << 7) +#define AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_SHIFT 8 +#define AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_KEEP 0 +#define AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_STRIP 1 +#define AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_ADD 2 +#define AR8X16_PORT_CTRL_EGRESS_VLAN_MODE_DOUBLE_TAG 3 +#define AR8X16_PORT_CTRL_IGMP_SNOOP (1 << 10) +#define AR8X16_PORT_CTRL_HEADER (1 << 11) +#define AR8X16_PORT_CTRL_MAC_LOOP (1 << 12) +#define AR8X16_PORT_CTRL_SINGLE_VLAN (1 << 13) +#define AR8X16_PORT_CTRL_LEARN (1 << 14) +#define AR8X16_PORT_CTRL_DOUBLE_TAG (1 << 15) +#define AR8X16_PORT_CTRL_MIRROR_TX (1 << 16) +#define AR8X16_PORT_CTRL_MIRROR_RX (1 << 17) + +#define AR8X16_REG_PORT_VLAN(_p) (AR8X16_REG_PORT_BASE((_p)) + 0x0008) + +#define AR8X16_PORT_VLAN_DEFAULT_ID_SHIFT 0 +#define AR8X16_PORT_VLAN_DEST_PORTS_SHIFT 16 +#define AR8X16_PORT_VLAN_MODE_MASK 0xc0000000 +#define AR8X16_PORT_VLAN_MODE_SHIFT 30 +#define AR8X16_PORT_VLAN_MODE_PORT_ONLY 0 +#define AR8X16_PORT_VLAN_MODE_PORT_FALLBACK 1 +#define AR8X16_PORT_VLAN_MODE_VLAN_ONLY 2 +#define AR8X16_PORT_VLAN_MODE_SECURE 3 + +#define AR8X16_REG_PORT_RATE_LIM(_p) (AR8X16_REG_PORT_BASE((_p)) + 0x000c) +#define AR8X16_PORT_RATE_LIM_128KB 0 +#define AR8X16_PORT_RATE_LIM_256KB 1 +#define AR8X16_PORT_RATE_LIM_512KB 2 +#define AR8X16_PORT_RATE_LIM_1MB 3 +#define AR8X16_PORT_RATE_LIM_2MB 4 +#define AR8X16_PORT_RATE_LIM_4MB 5 +#define AR8X16_PORT_RATE_LIM_8MB 6 +#define AR8X16_PORT_RATE_LIM_16MB 7 +#define AR8X16_PORT_RATE_LIM_32MB 8 +#define AR8X16_PORT_RATE_LIM_64MB 9 +#define AR8X16_PORT_RATE_LIM_IN_EN (1 << 24) +#define AR8X16_PORT_RATE_LIM_OUT_EN (1 << 23) +#define AR8X16_PORT_RATE_LIM_IN_MASK 0x000f0000 +#define AR8X16_PORT_RATE_LIM_IN_SHIFT 16 +#define AR8X16_PORT_RATE_LIM_OUT_MASK 0x0000000f +#define AR8X16_PORT_RATE_LIM_OUT_SHIFT 0 + +#define AR8X16_REG_PORT_PRIORITY(_p) (AR8X16_REG_PORT_BASE((_p)) + 0x0010) + +#define AR8X16_REG_STATS_BASE(_p) (0x20000 + (_p) * 0x100) + +#define AR8X16_STATS_RXBROAD 0x0000 +#define AR8X16_STATS_RXPAUSE 0x0004 +#define AR8X16_STATS_RXMULTI 0x0008 +#define AR8X16_STATS_RXFCSERR 0x000c +#define AR8X16_STATS_RXALIGNERR 0x0010 +#define AR8X16_STATS_RXRUNT 0x0014 +#define AR8X16_STATS_RXFRAGMENT 0x0018 +#define AR8X16_STATS_RX64BYTE 0x001c +#define AR8X16_STATS_RX128BYTE 0x0020 +#define AR8X16_STATS_RX256BYTE 0x0024 +#define AR8X16_STATS_RX512BYTE 0x0028 +#define AR8X16_STATS_RX1024BYTE 0x002c +#define AR8X16_STATS_RX1518BYTE 0x0030 +#define AR8X16_STATS_RXMAXBYTE 0x0034 +#define AR8X16_STATS_RXTOOLONG 0x0038 +#define AR8X16_STATS_RXGOODBYTE 0x003c +#define AR8X16_STATS_RXBADBYTE 0x0044 +#define AR8X16_STATS_RXOVERFLOW 0x004c +#define AR8X16_STATS_FILTERED 0x0050 +#define AR8X16_STATS_TXBROAD 0x0054 +#define AR8X16_STATS_TXPAUSE 0x0058 +#define AR8X16_STATS_TXMULTI 0x005c +#define AR8X16_STATS_TXUNDERRUN 0x0060 +#define AR8X16_STATS_TX64BYTE 0x0064 +#define AR8X16_STATS_TX128BYTE 0x0068 +#define AR8X16_STATS_TX256BYTE 0x006c +#define AR8X16_STATS_TX512BYTE 0x0070 +#define AR8X16_STATS_TX1024BYTE 0x0074 +#define AR8X16_STATS_TX1518BYTE 0x0078 +#define AR8X16_STATS_TXMAXBYTE 0x007c +#define AR8X16_STATS_TXOVERSIZE 0x0080 +#define AR8X16_STATS_TXBYTE 0x0084 +#define AR8X16_STATS_TXCOLLISION 0x008c +#define AR8X16_STATS_TXABORTCOL 0x0090 +#define AR8X16_STATS_TXMULTICOL 0x0094 +#define AR8X16_STATS_TXSINGLECOL 0x0098 +#define AR8X16_STATS_TXEXCDEFER 0x009c +#define AR8X16_STATS_TXDEFER 0x00a0 +#define AR8X16_STATS_TXLATECOL 0x00a4 + +#define AR8X16_PORT_CPU 0 +#define AR8X16_NUM_PORTS 6 +#define AR8X16_NUM_PHYS 5 +#define AR8X16_MAGIC 0xc000050e + +#define AR8X16_PHY_ID1 0x004d +#define AR8X16_PHY_ID2 0xd041 + +#define AR8X16_PORT_MASK(_port) (1 << (_port)) +#define AR8X16_PORT_MASK_ALL ((1<parent, phy, reg) +#define MII_WRITE(sc, phy, reg, val) \ + MIIBUS_WRITEREG(sc->parent, phy, reg, val) + +#define REG_REG(reg) (((reg) >> 1) & 0x01e) +#define REG_PHY(reg) (((reg) >> 6) & 0x007) +#define REG_PAGE(reg) (((reg) >> 9) & 0x1ff) +#define VLAN_IDX_VALID 0x8000 + +#define SET4(sc, reg, mask, val) \ + WRITE4(sc, reg, (READ4(sc, reg) & ~mask) | val) + +#define WAIT4(sc, reg, field, value, timeout_usec) \ + ({int result; \ + do { \ + uint32_t c, timeout = timeout_usec; \ + while (1) { \ + c = (READ4(sc, reg) & field); \ + if (c == (value)) { \ + result = 0; \ + break; \ + } else if (!timeout) { \ + result = -1; \ + break; \ + } else { \ + DELAY(1); timeout--; \ + } \ + } \ + } while (0); \ + result;}) + +#endif /* _AR8X16_SWITCHVAR_H_ */ diff --git a/sys/dev/etherswitch/etherswitch.c b/sys/dev/etherswitch/etherswitch.c new file mode 100644 index 0000000..a216289 --- /dev/null +++ b/sys/dev/etherswitch/etherswitch.c @@ -0,0 +1,257 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "etherswitch_if.h" + +#define BUFSIZE 1024 + +struct etherswitch_softc { + device_t sc_dev; + int sc_count; + + struct cdev *sc_devnode; + struct sx sc_lock; +}; + +#define SWITCH_LOCK(sc) sx_xlock(&(sc)->sc_lock) +#define SWITCH_UNLOCK(sc) sx_xunlock(&(sc)->sc_lock) + +static int etherswitch_probe(device_t); +static int etherswitch_attach(device_t); +static int etherswitch_detach(device_t); +static void etherswitch_identify(driver_t *driver, device_t parent); + +devclass_t etherswitch_devclass; + +static device_method_t etherswitch_methods[] = { + /* device interface */ + DEVMETHOD(device_identify, etherswitch_identify), + DEVMETHOD(device_probe, etherswitch_probe), + DEVMETHOD(device_attach, etherswitch_attach), + DEVMETHOD(device_detach, etherswitch_detach), + + { 0, 0 } +}; + +driver_t etherswitch_driver = { + "etherswitch", + etherswitch_methods, + sizeof(struct etherswitch_softc), +}; + +static d_open_t etherswitchopen; +static d_close_t etherswitchclose; +static d_write_t etherswitchwrite; +static d_read_t etherswitchread; +static d_ioctl_t etherswitchioctl; + +static struct cdevsw etherswitch_cdevsw = { + .d_version = D_VERSION, + .d_flags = D_TRACKCLOSE, + .d_open = etherswitchopen, + .d_close = etherswitchclose, + .d_read = etherswitchread, + .d_write = etherswitchwrite, + .d_ioctl = etherswitchioctl, + .d_name = "etherswitch", +}; + +static void +etherswitch_identify(driver_t *driver, device_t parent) +{ + if (device_find_child(parent, "etherswitch", -1) == NULL) + BUS_ADD_CHILD(parent, 0, "etherswitch", -1); +} + +static int +etherswitch_probe(device_t dev) +{ + device_set_desc(dev, "Switch controller"); + + return (0); +} + +static int +etherswitch_attach(device_t dev) +{ + struct etherswitch_softc *sc = (struct etherswitch_softc *)device_get_softc(dev); + + sc->sc_dev = dev; + sx_init(&sc->sc_lock, "etherswitch"); + sc->sc_devnode = make_dev(ðerswitch_cdevsw, device_get_unit(dev), + UID_ROOT, GID_WHEEL, + 0600, "etherswitch%d", device_get_unit(dev)); + if (sc->sc_devnode == NULL) { + device_printf(dev, "failed to create character device\n"); + sx_destroy(&sc->sc_lock); + return (ENXIO); + } + sc->sc_devnode->si_drv1 = sc; + + return (0); +} + +static int +etherswitch_detach(device_t dev) +{ + struct etherswitch_softc *sc = (struct etherswitch_softc *)device_get_softc(dev); + + if (sc->sc_devnode) + destroy_dev(sc->sc_devnode); + sx_destroy(&sc->sc_lock); + + return (0); +} + +static int +etherswitchopen(struct cdev *dev, int flags, int fmt, struct thread *td) +{ + struct etherswitch_softc *sc = dev->si_drv1; + + SWITCH_LOCK(sc); + if (sc->sc_count > 0) { + SWITCH_UNLOCK(sc); + return (EBUSY); + } + + sc->sc_count++; + SWITCH_UNLOCK(sc); + + return (0); +} + +static int +etherswitchclose(struct cdev *dev, int flags, int fmt, struct thread *td) +{ + struct etherswitch_softc *sc = dev->si_drv1; + + SWITCH_LOCK(sc); + if (sc->sc_count == 0) { + SWITCH_UNLOCK(sc); + return (EINVAL); + } + + sc->sc_count--; + + if (sc->sc_count < 0) + panic("%s: etherswitch_count < 0!", __func__); + SWITCH_UNLOCK(sc); + + return (0); +} + +static int +etherswitchwrite(struct cdev *dev, struct uio * uio, int ioflag) +{ + return (EINVAL); +} + +static int +etherswitchread(struct cdev *dev, struct uio * uio, int ioflag) +{ + return (EINVAL); +} + +static int +etherswitchioctl(struct cdev *cdev, u_long cmd, caddr_t data, int flags, struct thread *td) +{ + struct etherswitch_softc *sc = cdev->si_drv1; + device_t dev = sc->sc_dev; + device_t etherswitch = device_get_parent(dev); + etherswitch_info_t *info; + etherswitch_reg_t *reg; + etherswitch_phyreg_t *phyreg; + int error = 0; + + switch (cmd) { + case IOETHERSWITCHGETINFO: + info = ETHERSWITCH_GETINFO(etherswitch); + bcopy(info, data, sizeof(etherswitch_info_t)); + break; + + case IOETHERSWITCHGETREG: + reg = (etherswitch_reg_t *)data; + reg->val = ETHERSWITCH_READREG(etherswitch, reg->reg); + break; + + case IOETHERSWITCHSETREG: + reg = (etherswitch_reg_t *)data; + error = ETHERSWITCH_WRITEREG(etherswitch, reg->reg, reg->val); + break; + + case IOETHERSWITCHGETPORT: + error = ETHERSWITCH_GETPORT(etherswitch, (etherswitch_port_t *)data); + break; + + case IOETHERSWITCHSETPORT: + error = ETHERSWITCH_SETPORT(etherswitch, (etherswitch_port_t *)data); + break; + + case IOETHERSWITCHGETVLANGROUP: + error = ETHERSWITCH_GETVGROUP(etherswitch, (etherswitch_vlangroup_t *)data); + break; + + case IOETHERSWITCHSETVLANGROUP: + error = ETHERSWITCH_SETVGROUP(etherswitch, (etherswitch_vlangroup_t *)data); + break; + + case IOETHERSWITCHGETPHYREG: + phyreg = (etherswitch_phyreg_t *)data; + phyreg->val = ETHERSWITCH_READPHYREG(etherswitch, phyreg->phy, phyreg->reg); + break; + + case IOETHERSWITCHSETPHYREG: + phyreg = (etherswitch_phyreg_t *)data; + error = ETHERSWITCH_WRITEPHYREG(etherswitch, phyreg->phy, phyreg->reg, phyreg->val); + break; + + default: + error = ENOTTY; + } + + return (error); +} + +MODULE_VERSION(etherswitch, 1); diff --git a/sys/dev/etherswitch/etherswitch.h b/sys/dev/etherswitch/etherswitch.h new file mode 100644 index 0000000..90ecb48 --- /dev/null +++ b/sys/dev/etherswitch/etherswitch.h @@ -0,0 +1,69 @@ +/* + * $FreeBSD$ + */ + +#ifndef __SYS_DEV_ETHERSWITCH_ETHERSWITCH_H +#define __SYS_DEV_ETHERSWITCH_ETHERSWITCH_H + +#include + +#ifdef _KERNEL +extern devclass_t etherswitch_devclass; +extern driver_t etherswitch_driver; +#endif /* _KERNEL */ + +struct etherswitch_reg { + uint16_t reg; + uint16_t val; +}; +typedef struct etherswitch_reg etherswitch_reg_t; + +struct etherswitch_phyreg { + uint16_t phy; + uint16_t reg; + uint16_t val; +}; +typedef struct etherswitch_phyreg etherswitch_phyreg_t; + +#define ETHERSWITCH_NAMEMAX 64 + +struct etherswitch_info { + int es_nports; + int es_nvlangroups; + char es_name[ETHERSWITCH_NAMEMAX]; +}; +typedef struct etherswitch_info etherswitch_info_t; + +struct etherswitch_port { + int es_port; + int es_vlangroup; + union { + struct ifreq es_uifr; + struct ifmediareq es_uifmr; + } es_ifu; +#define es_ifr es_ifu.es_uifr +#define es_ifmr es_ifu.es_uifmr +}; +typedef struct etherswitch_port etherswitch_port_t; + +struct etherswitch_vlangroup { + int es_vlangroup; + int es_vid; + int es_member_ports; + int es_untagged_ports; + int es_fid; +}; +typedef struct etherswitch_vlangroup etherswitch_vlangroup_t; +#define ETHERSWITCH_PORTMASK(_port) (1 << (_port)) + +#define IOETHERSWITCHGETINFO _IOR('i', 1, etherswitch_info_t) +#define IOETHERSWITCHGETREG _IOWR('i', 2, etherswitch_reg_t) +#define IOETHERSWITCHSETREG _IOW('i', 3, etherswitch_reg_t) +#define IOETHERSWITCHGETPORT _IOWR('i', 4, etherswitch_port_t) +#define IOETHERSWITCHSETPORT _IOW('i', 5, etherswitch_port_t) +#define IOETHERSWITCHGETVLANGROUP _IOWR('i', 6, etherswitch_vlangroup_t) +#define IOETHERSWITCHSETVLANGROUP _IOW('i', 7, etherswitch_vlangroup_t) +#define IOETHERSWITCHGETPHYREG _IOWR('i', 8, etherswitch_phyreg_t) +#define IOETHERSWITCHSETPHYREG _IOW('i', 9, etherswitch_phyreg_t) + +#endif diff --git a/sys/dev/etherswitch/etherswitch_if.m b/sys/dev/etherswitch/etherswitch_if.m new file mode 100644 index 0000000..7429c04 --- /dev/null +++ b/sys/dev/etherswitch/etherswitch_if.m @@ -0,0 +1,86 @@ +# $FreeBSD$ + +#include + +# Needed for ifreq/ifmediareq +#include +#include + +#include + +INTERFACE etherswitch; + +# +# Return device info +# +METHOD etherswitch_info_t* getinfo { + device_t dev; +} + +# +# Read switch register +# +METHOD int readreg { + device_t dev; + int reg; +}; + +# +# Write switch register +# +METHOD int writereg { + device_t dev; + int reg; + int value; +}; + +# +# Read PHY register +# +METHOD int readphyreg { + device_t dev; + int phy; + int reg; +}; + +# +# Write PHY register +# +METHOD int writephyreg { + device_t dev; + int phy; + int reg; + int value; +}; + +# +# Get port configuration +# +METHOD int getport { + device_t dev; + etherswitch_port_t *vg; +} + +# +# Set port configuration +# +METHOD int setport { + device_t dev; + etherswitch_port_t *vg; +} + +# +# Get VLAN group configuration +# +METHOD int getvgroup { + device_t dev; + etherswitch_vlangroup_t *vg; +} + +# +# Set VLAN group configuration +# +METHOD int setvgroup { + device_t dev; + etherswitch_vlangroup_t *vg; +} diff --git a/sys/dev/etherswitch/mdio.c b/sys/dev/etherswitch/mdio.c new file mode 100644 index 0000000..9302075 --- /dev/null +++ b/sys/dev/etherswitch/mdio.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include + +#include + +#include "mdio_if.h" + +static void +mdio_identify(driver_t *driver, device_t parent) +{ + if (device_find_child(parent, mdio_driver.name, -1) == NULL) + BUS_ADD_CHILD(parent, 0, mdio_driver.name, -1); +} + +static int +mdio_probe(device_t dev) +{ + device_set_desc(dev, "MDIO"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +mdio_attach(device_t dev) +{ + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + return (bus_generic_attach(dev)); +} + +static int +mdio_detach(device_t dev) +{ + bus_generic_detach(dev); + return (0); +} + +static int +mdio_readreg(device_t dev, int phy, int reg) +{ + return MDIO_READREG(device_get_parent(dev), phy, reg); +} + +static int +mdio_writereg(device_t dev, int phy, int reg, int val) +{ + return MDIO_WRITEREG(device_get_parent(dev), phy, reg, val); +} + +static int +mdio_print_child(device_t dev, device_t child) +{ + int retval; + + retval = bus_print_child_header(dev, child); + retval += bus_print_child_footer(dev, child); + + return (retval); +} + +static int +mdio_read_ivar(device_t dev, device_t child __unused, int which, + uintptr_t *result) +{ + struct miibus_ivars *ivars; + + ivars = device_get_ivars(dev); + switch (which) { + default: + return (ENOENT); + } + return (0); +} + +static int +mdio_child_pnpinfo_str(device_t dev __unused, device_t child, char *buf, + size_t buflen) +{ + buf[0] = '\0'; + return (0); +} + +static int +mdio_child_location_str(device_t dev __unused, device_t child, char *buf, + size_t buflen) +{ + buf[0] = '\0'; + return (0); +} + +static void +mdio_hinted_child(device_t dev, const char *name, int unit) +{ + device_add_child(dev, name, unit); +} + +static device_method_t mdio_methods[] = { + /* device interface */ + DEVMETHOD(device_identify, mdio_identify), + DEVMETHOD(device_probe, mdio_probe), + DEVMETHOD(device_attach, mdio_attach), + DEVMETHOD(device_detach, mdio_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* bus interface */ + DEVMETHOD(bus_print_child, mdio_print_child), + DEVMETHOD(bus_read_ivar, mdio_read_ivar), + DEVMETHOD(bus_child_pnpinfo_str, mdio_child_pnpinfo_str), + DEVMETHOD(bus_child_location_str, mdio_child_location_str), + DEVMETHOD(bus_add_child, device_add_child_ordered), + DEVMETHOD(bus_hinted_child, mdio_hinted_child), + + /* MDIO access */ + DEVMETHOD(mdio_readreg, mdio_readreg), + DEVMETHOD(mdio_writereg, mdio_writereg), + + DEVMETHOD_END +}; + +driver_t mdio_driver = { + "mdio", + mdio_methods, + 0 +}; + +devclass_t mdio_devclass; + diff --git a/sys/dev/etherswitch/mdio.h b/sys/dev/etherswitch/mdio.h new file mode 100644 index 0000000..52eddbd --- /dev/null +++ b/sys/dev/etherswitch/mdio.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 _DEV_MII_MDIO_H_ +#define _DEV_MII_MDIO_H_ + +extern driver_t mdio_driver; +extern devclass_t mdio_devclass; + +#endif diff --git a/sys/dev/etherswitch/mdio_if.m b/sys/dev/etherswitch/mdio_if.m new file mode 100644 index 0000000..9aedd92 --- /dev/null +++ b/sys/dev/etherswitch/mdio_if.m @@ -0,0 +1,24 @@ +# $FreeBSD$ + +#include + +INTERFACE mdio; + +# +# Read register from device on MDIO bus +# +METHOD int readreg { + device_t dev; + int phy; + int reg; +}; + +# +# Write register to device on MDIO bus +# +METHOD int writereg { + device_t dev; + int phy; + int reg; + int val; +}; diff --git a/sys/dev/etherswitch/miiproxy.c b/sys/dev/etherswitch/miiproxy.c new file mode 100644 index 0000000..2791082 --- /dev/null +++ b/sys/dev/etherswitch/miiproxy.c @@ -0,0 +1,437 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mdio_if.h" +#include "miibus_if.h" + + +MALLOC_DECLARE(M_MIIPROXY); +MALLOC_DEFINE(M_MIIPROXY, "miiproxy", "miiproxy data structures"); + +driver_t miiproxy_driver; +driver_t mdioproxy_driver; + +struct miiproxy_softc { + device_t parent; + device_t proxy; + device_t mdio; + miiproxy_attach_callback_t attach_callback; + void *attach_arg; +}; + +struct mdioproxy_softc { +}; + +/* + * The rendevous data structures and functions allow two device endpoints to + * match up, so that the proxy endpoint can be associated with a target + * endpoint. The proxy has to know the device name of the target that it + * wants to associate with, for example through a hint. The rendevous code + * makes no assumptions about the devices that want to meet. + */ +struct rendevous_entry; + +enum rendevous_op { + RENDEVOUS_ATTACH, + RENDEVOUS_DETACH +}; + +typedef int (*rendevous_callback_t)(enum rendevous_op, + struct rendevous_entry *); + +static SLIST_HEAD(rendevoushead, rendevous_entry) rendevoushead = + SLIST_HEAD_INITIALIZER(rendevoushead); + +struct rendevous_endpoint { + device_t device; + const char *name; + rendevous_callback_t callback; +}; + +struct rendevous_entry { + SLIST_ENTRY(rendevous_entry) entries; + struct rendevous_endpoint proxy; + struct rendevous_endpoint target; +}; + +/* + * Call the callback routines for both the proxy and the target. If either + * returns an error, undo the attachment. + */ +static int +rendevous_attach(struct rendevous_entry *e, struct rendevous_endpoint *ep) +{ + int error; + + error = e->proxy.callback(RENDEVOUS_ATTACH, e); + if (error == 0) + error = e->target.callback(RENDEVOUS_ATTACH, e); + if (error != 0) { + e->proxy.callback(RENDEVOUS_DETACH, e); + ep->device = NULL; + ep->callback = NULL; + } + return (error); +} + +/* + * Create an entry for the proxy in the rendevous list. The name parameter + * indicates the name of the device that is the target endpoint for this + * rendevous. The callback will be invoked as soon as the target is + * registered: either immediately if the target registered itself earlier, + * or once the target registers. + */ +static int +rendevous_register_proxy(device_t dev, const char *name, + rendevous_callback_t callback) +{ + struct rendevous_entry *e; + + KASSERT(callback != NULL, ("callback must not be NULL")); + SLIST_FOREACH(e, &rendevoushead, entries) { + if (strcmp(name, e->target.name) == 0) { + /* the target is already attached */ + e->proxy.name = device_get_nameunit(dev); + e->proxy.device = dev; + e->proxy.callback = callback; + return (rendevous_attach(e, &e->proxy)); + } + } + e = malloc(sizeof(*e), M_MIIPROXY, M_WAITOK | M_ZERO); + e->proxy.name = device_get_nameunit(dev); + e->proxy.device = dev; + e->proxy.callback = callback; + e->target.name = name; + SLIST_INSERT_HEAD(&rendevoushead, e, entries); + return (0); +} + +/* + * Create an entry in the rendevous list for the target. The callback will + * be called once the proxy has registered. + */ +static int +rendevous_register_target(device_t dev, rendevous_callback_t callback) +{ + struct rendevous_entry *e; + const char *name; + + KASSERT(callback != NULL, ("callback must not be NULL")); + name = device_get_nameunit(dev); + SLIST_FOREACH(e, &rendevoushead, entries) { + if (strcmp(name, e->target.name) == 0) { + e->target.device = dev; + e->target.callback = callback; + return (rendevous_attach(e, &e->target)); + } + } + e = malloc(sizeof(*e), M_MIIPROXY, M_WAITOK | M_ZERO); + e->target.name = name; + e->target.device = dev; + e->target.callback = callback; + SLIST_INSERT_HEAD(&rendevoushead, e, entries); + return (0); +} + +/* + * Remove the registration for the proxy. + */ +static int +rendevous_unregister_proxy(device_t dev) +{ + struct rendevous_entry *e; + int error = 0; + + SLIST_FOREACH(e, &rendevoushead, entries) { + if (e->proxy.device == dev) { + if (e->target.device == NULL) { + SLIST_REMOVE(&rendevoushead, e, rendevous_entry, entries); + free(e, M_MIIPROXY); + return (0); + } else { + e->proxy.callback(RENDEVOUS_DETACH, e); + e->target.callback(RENDEVOUS_DETACH, e); + } + e->proxy.device = NULL; + e->proxy.callback = NULL; + return (error); + } + } + return (ENOENT); +} + +/* + * Remove the registration for the target. + */ +static int +rendevous_unregister_target(device_t dev) +{ + struct rendevous_entry *e; + int error = 0; + + SLIST_FOREACH(e, &rendevoushead, entries) { + if (e->target.device == dev) { + if (e->proxy.device == NULL) { + SLIST_REMOVE(&rendevoushead, e, rendevous_entry, entries); + free(e, M_MIIPROXY); + return (0); + } else { + e->proxy.callback(RENDEVOUS_DETACH, e); + e->target.callback(RENDEVOUS_DETACH, e); + } + e->target.device = NULL; + e->target.callback = NULL; + return (error); + } + } + return (ENOENT); +} + +/* + * Functions of the proxy that is interposed between the ethernet interface + * driver and the miibus device. + */ + +static int +miiproxy_rendevous_callback(enum rendevous_op op, struct rendevous_entry *rendevous) +{ + struct miiproxy_softc *sc = device_get_softc(rendevous->proxy.device); + + switch (op) { + case RENDEVOUS_ATTACH: + sc->mdio = device_get_parent(rendevous->target.device); + (sc->attach_callback)(sc->attach_arg); + break; + case RENDEVOUS_DETACH: + sc->mdio = NULL; + /* detach miibus */ + } + return (0); +} + +static int +miiproxy_probe(device_t dev) +{ + device_set_desc(dev, "MII/MDIO proxy, MII side"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +miiproxy_attach(device_t dev) +{ + /* + * The ethernet interface needs to call mii_attach_proxy() to pass + * the relevant parameters for rendevous with the MDIO target. + */ + return (bus_generic_attach(dev)); +} + +static int +miiproxy_detach(device_t dev) +{ + rendevous_unregister_proxy(dev); + bus_generic_detach(dev); + return (0); +} + +static int +miiproxy_readreg(device_t dev, int phy, int reg) +{ + struct miiproxy_softc *sc = device_get_softc(dev); + + if (sc->mdio != NULL) + return (MDIO_READREG(sc->mdio, phy, reg)); + return (-1); +} + +static int +miiproxy_writereg(device_t dev, int phy, int reg, int val) +{ + struct miiproxy_softc *sc = device_get_softc(dev); + + if (sc->mdio != NULL) + return (MDIO_WRITEREG(sc->mdio, phy, reg, val)); + return (-1); +} + +static void +miiproxy_statchg(device_t dev) +{ + MIIBUS_STATCHG(device_get_parent(dev)); +} + +static void +miiproxy_linkchg(device_t dev) +{ + MIIBUS_LINKCHG(device_get_parent(dev)); +} + +static void +miiproxy_mediainit(device_t dev) +{ + MIIBUS_MEDIAINIT(device_get_parent(dev)); +} + +/* + * Functions for the MDIO target device driver. + */ +static int +mdioproxy_rendevous_callback(enum rendevous_op op, struct rendevous_entry *rendevous) +{ + return (0); +} + +static void +mdioproxy_identify(driver_t *driver, device_t parent) +{ + device_t child; + + if (device_find_child(parent, driver->name, -1) == NULL) { + child = BUS_ADD_CHILD(parent, 0, driver->name, -1); + } +} + +static int +mdioproxy_probe(device_t dev) +{ + device_set_desc(dev, "MII/MDIO proxy, MDIO side"); + + return (BUS_PROBE_SPECIFIC); +} + +static int +mdioproxy_attach(device_t dev) +{ + rendevous_register_target(dev, mdioproxy_rendevous_callback); + return (bus_generic_attach(dev)); +} + +static int +mdioproxy_detach(device_t dev) +{ + rendevous_unregister_target(dev); + bus_generic_detach(dev); + return (0); +} + +/* + * Attach this proxy in place of miibus. The callback is called once all + * parts are in place, so that it can attach the miibus to the proxy device, + * and finish interface initialization. + */ +device_t +mii_attach_proxy(device_t dev, miiproxy_attach_callback_t cb, void *aa) +{ + struct miiproxy_softc *sc; + int error; + const char *name; + device_t miiproxy; + + if (resource_string_value(device_get_name(dev), + device_get_unit(dev), "mdio", &name) != 0) { + if (bootverbose) + printf("mii_attach_proxy: not attaching, no mdio" + " device hint for %s\n", device_get_nameunit(dev)); + return (NULL); + } + + miiproxy = device_add_child(dev, miiproxy_driver.name, -1); + error = bus_generic_attach(dev); + if (error != 0) { + device_printf(dev, "can't attach miiproxy\n"); + return (NULL); + } + sc = device_get_softc(miiproxy); + sc->parent = dev; + sc->proxy = miiproxy; + sc->attach_callback = cb; + sc->attach_arg = aa; + rendevous_register_proxy(miiproxy, name, miiproxy_rendevous_callback); + return (miiproxy); +} + +static device_method_t miiproxy_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, miiproxy_probe), + DEVMETHOD(device_attach, miiproxy_attach), + DEVMETHOD(device_detach, miiproxy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* MII interface */ + DEVMETHOD(miibus_readreg, miiproxy_readreg), + DEVMETHOD(miibus_writereg, miiproxy_writereg), + DEVMETHOD(miibus_statchg, miiproxy_statchg), + DEVMETHOD(miibus_linkchg, miiproxy_linkchg), + DEVMETHOD(miibus_mediainit, miiproxy_mediainit), + + DEVMETHOD_END +}; + +static device_method_t mdioproxy_methods[] = { + /* device interface */ + DEVMETHOD(device_identify, mdioproxy_identify), + DEVMETHOD(device_probe, mdioproxy_probe), + DEVMETHOD(device_attach, mdioproxy_attach), + DEVMETHOD(device_detach, mdioproxy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(miiproxy, miiproxy_driver, miiproxy_methods, + sizeof(struct miiproxy_softc)); +DEFINE_CLASS_0(mdioproxy, mdioproxy_driver, mdioproxy_methods, + sizeof(struct mdioproxy_softc)); + +devclass_t miiproxy_devclass; +static devclass_t mdioproxy_devclass; + +DRIVER_MODULE(mdioproxy, mdio, mdioproxy_driver, mdioproxy_devclass, 0, 0); +DRIVER_MODULE(miibus, miiproxy, miibus_driver, miibus_devclass, 0, 0); +MODULE_VERSION(miiproxy, 1); +MODULE_DEPEND(miiproxy, miibus, 1, 1, 1); diff --git a/sys/dev/etherswitch/miiproxy.h b/sys/dev/etherswitch/miiproxy.h new file mode 100644 index 0000000..5b8ee7c --- /dev/null +++ b/sys/dev/etherswitch/miiproxy.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 _DEV_ETHERSWITCH_MIIPROXY_H_ +#define _DEV_ETHERSWITCH_MIIPROXY_H_ + +typedef void (*miiproxy_attach_callback_t)(void *); + +extern devclass_t miiproxy_devclass; +extern driver_t miiproxy_driver; + +device_t mii_attach_proxy(device_t dev, miiproxy_attach_callback_t cb, void *aa); + +#endif diff --git a/sys/dev/etherswitch/rtl8366rb.c b/sys/dev/etherswitch/rtl8366rb.c new file mode 100644 index 0000000..afc6eef --- /dev/null +++ b/sys/dev/etherswitch/rtl8366rb.c @@ -0,0 +1,755 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "iicbus_if.h" +#include "miibus_if.h" +#include "etherswitch_if.h" + + +struct rtl8366rb_softc { + struct mtx sc_mtx; /* serialize access to softc */ + int smi_acquired; /* serialize access to SMI/I2C bus */ + struct mtx callout_mtx; /* serialize callout */ + device_t dev; + char *ifname[RTL8366RB_NUM_PHYS]; + device_t miibus[RTL8366RB_NUM_PHYS]; + struct ifnet *ifp[RTL8366RB_NUM_PHYS]; + struct callout callout_tick; +}; + +static etherswitch_info_t etherswitch_info = { + .es_nports = 6, + .es_nvlangroups = 16, + .es_name = "Realtek RTL8366RB" +}; + +#define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define RTL_LOCK_ASSERT(_sc, _what) mtx_assert(&(_s)c->sc_mtx, (_what)) +#define RTL_TRYLOCK(_sc) mtx_trylock(&(_sc)->sc_mtx) + +#define RTL_WAITOK 0 +#define RTL_NOWAIT 1 + +#define RTL_SMI_ACQUIRED 1 +#define RTL_SMI_ACQUIRED_ASSERT(_sc) \ + KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__)) + +#if defined(DEBUG) +#define DPRINTF(dev, args...) device_printf(dev, args) +#define DEVERR(dev, err, fmt, args...) do { \ + if (err != 0) device_printf(dev, fmt, err, args); \ + } while (0) +#define DEBUG_INCRVAR(var) do { \ + var++; \ + } while (0) + +static int callout_blocked = 0; +static int iic_select_retries = 0; +static int phy_access_retries = 0; +static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD, 0, "rtl8366rb"); +SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0, + "number of times the callout couldn't acquire the bus"); +SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, iic_select_retries, CTLFLAG_RW, &iic_select_retries, 0, + "number of times the I2C bus selection had to be retried"); +SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, phy_access_retries, CTLFLAG_RW, &phy_access_retries, 0, + "number of times PHY register access had to be retried"); +#else +#define DPRINTF(dev, args...) +#define DEVERR(dev, err, fmt, args...) +#define DEBUG_INCRVAR(var) +#endif + +static int smi_probe(device_t dev); +static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep); +static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep); +static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep); +static void rtl8366rb_tick(void *arg); +static int rtl8366rb_ifmedia_upd(struct ifnet *); +static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *); + +static void +rtl8366rb_identify(driver_t *driver, device_t parent) +{ + device_t child; + struct iicbus_ivar *devi; + + if (device_find_child(parent, "rtl8366rb", -1) == NULL) { + child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1); + devi = IICBUS_IVAR(child); + devi->addr = RTL8366RB_IIC_ADDR; + } +} + +static int +rtl8366rb_probe(device_t dev) +{ + if (smi_probe(dev) != 0) + return (ENXIO); + device_set_desc(dev, "RTL8366RB Ethernet Switch Controller"); + return (BUS_PROBE_DEFAULT); +} + +static void +rtl8366rb_init(device_t dev) +{ + /* Initialisation for TL-WR1043ND */ + smi_rmw(dev, RTL8366RB_RCR, + RTL8366RB_RCR_HARD_RESET, + RTL8366RB_RCR_HARD_RESET, RTL_WAITOK); + DELAY(100000); + /* Enable 16 VLAN mode */ + smi_rmw(dev, RTL8366RB_SGCR, + RTL8366RB_SGCR_EN_VLAN | RTL8366RB_SGCR_EN_VLAN_4KTB, + RTL8366RB_SGCR_EN_VLAN, RTL_WAITOK); + /* remove port 0 form VLAN 0 */ + smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 0), + (1 << 0), 0, RTL_WAITOK); + /* add port 0 untagged and port 5 tagged to VLAN 1 */ + smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 1), + ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT) + | ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT), + ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT + | ((1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT)), + RTL_WAITOK); + /* set PVLAN 1 for port 0 */ + smi_rmw(dev, RTL8366RB_PVCR_REG(0), + RTL8366RB_PVCR_VAL(0, RTL8366RB_PVCR_PORT_MASK), + RTL8366RB_PVCR_VAL(0, 1), RTL_WAITOK); +} + +static int +rtl8366rb_attach(device_t dev) +{ + uint16_t rev = 0; + struct rtl8366rb_softc *sc; + char name[IFNAMSIZ]; + int err = 0; + int i; + + sc = device_get_softc(dev); + bzero(sc, sizeof(*sc)); + sc->dev = dev; + mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF); + sc->smi_acquired = 0; + mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF); + + rtl8366rb_init(dev); + smi_read(dev, RTL8366RB_CVCR, &rev, RTL_WAITOK); + device_printf(dev, "rev. %d\n", rev & 0x000f); + + /* attach miibus and phys */ + /* PHYs need an interface, so we generate a dummy one */ + for (i = 0; i < RTL8366RB_NUM_PHYS; i++) { + sc->ifp[i] = if_alloc(IFT_ETHER); + sc->ifp[i]->if_softc = sc; + sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING + | IFF_SIMPLEX; + snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(dev)); + sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK); + bcopy(name, sc->ifname[i], strlen(name)+1); + if_initname(sc->ifp[i], sc->ifname[i], i); + err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \ + rtl8366rb_ifmedia_sts, BMSR_DEFCAPMASK, \ + i, MII_OFFSET_ANY, 0); + if (err != 0) { + device_printf(dev, "attaching PHY %d failed\n", i); + return (err); + } + } + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + err = bus_generic_attach(dev); + if (err != 0) + return (err); + + callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0); + rtl8366rb_tick(sc); + + return (err); +} + +static int +rtl8366rb_detach(device_t dev) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + int i; + + for (i=0; i < RTL8366RB_NUM_PHYS; i++) { + if (sc->miibus[i]) + device_delete_child(dev, sc->miibus[i]); + if (sc->ifp[i] != NULL) + if_free(sc->ifp[i]); + free(sc->ifname[i], M_DEVBUF); + } + bus_generic_detach(dev); + callout_drain(&sc->callout_tick); + mtx_destroy(&sc->callout_mtx); + mtx_destroy(&sc->sc_mtx); + + return (0); +} + +static void +rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active) +{ + *media_active = IFM_ETHER; + *media_status = IFM_AVALID; + if ((portstatus & RTL8366RB_PLSR_LINK) != 0) + *media_status |= IFM_ACTIVE; + else { + *media_active |= IFM_NONE; + return; + } + switch (portstatus & RTL8366RB_PLSR_SPEED_MASK) { + case RTL8366RB_PLSR_SPEED_10: + *media_active |= IFM_10_T; + break; + case RTL8366RB_PLSR_SPEED_100: + *media_active |= IFM_100_TX; + break; + case RTL8366RB_PLSR_SPEED_1000: + *media_active |= IFM_1000_T; + break; + } + if ((portstatus & RTL8366RB_PLSR_FULLDUPLEX) == 0) + *media_active |= IFM_FDX; + else + *media_active |= IFM_HDX; + if ((portstatus & RTL8366RB_PLSR_TXPAUSE) != 0) + *media_active |= IFM_ETH_TXPAUSE; + if ((portstatus & RTL8366RB_PLSR_RXPAUSE) != 0) + *media_active |= IFM_ETH_RXPAUSE; +} + +static void +rtl833rb_miipollstat(struct rtl8366rb_softc *sc) +{ + int i; + struct mii_data *mii; + struct mii_softc *miisc; + uint16_t value; + int portstatus; + + for (i = 0; i < RTL8366RB_NUM_PHYS; i++) { + mii = device_get_softc(sc->miibus[i]); + if ((i % 2) == 0) { + if (smi_read(sc->dev, RTL8366RB_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) { + DEBUG_INCRVAR(callout_blocked); + return; + } + portstatus = value & 0xff; + } else { + portstatus = (value >> 8) & 0xff; + } + rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active); + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) { + if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst) + continue; + mii_phy_update(miisc, MII_POLLSTAT); + } + } +} + +static void +rtl8366rb_tick(void *arg) +{ + struct rtl8366rb_softc *sc = arg; + + rtl833rb_miipollstat(sc); + callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc); +} + +static int +smi_probe(device_t dev) +{ + device_t iicbus, iicha; + int err, i; + uint16_t chipid; + char bytes[2]; + int xferd; + + bytes[0] = RTL8366RB_CIR & 0xff; + bytes[1] = (RTL8366RB_CIR >> 8) & 0xff; + iicbus = device_get_parent(dev); + iicha = device_get_parent(iicbus); + iicbus_reset(iicbus, IIC_FASTEST, RTL8366RB_IIC_ADDR, NULL); + for (i=3; i--; ) { + IICBUS_STOP(iicha); + /* + * we go directly to the host adapter because iicbus.c + * only issues a stop on a bus that was successfully started. + */ + } + err = iicbus_request_bus(iicbus, dev, IIC_WAIT); + if (err != 0) + goto out; + err = iicbus_start(iicbus, RTL8366RB_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT); + if (err != 0) + goto out; + err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT); + if (err != 0) + goto out; + err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0); + if (err != 0) + goto out; + chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff); + DPRINTF(dev, "chip id 0x%04x\n", chipid); + if (chipid != RTL8366RB_CIR_ID8366RB) + err = ENXIO; +out: + iicbus_stop(iicbus); + iicbus_release_bus(iicbus, dev); + return (err == 0 ? 0 : ENXIO); +} + +static int +smi_acquire(struct rtl8366rb_softc *sc, int sleep) +{ + int r = 0; + if (sleep == RTL_WAITOK) + RTL_LOCK(sc); + else + if (RTL_TRYLOCK(sc) == 0) + return (EWOULDBLOCK); + if (sc->smi_acquired == RTL_SMI_ACQUIRED) + r = EBUSY; + else { + r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \ + sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT); + if (r == 0) + sc->smi_acquired = RTL_SMI_ACQUIRED; + } + RTL_UNLOCK(sc); + return (r); +} + +static int +smi_release(struct rtl8366rb_softc *sc, int sleep) +{ + if (sleep == RTL_WAITOK) + RTL_LOCK(sc); + else + if (RTL_TRYLOCK(sc) == 0) + return (EWOULDBLOCK); + RTL_SMI_ACQUIRED_ASSERT(sc); + iicbus_release_bus(device_get_parent(sc->dev), sc->dev); + sc->smi_acquired = 0; + RTL_UNLOCK(sc); + return (0); +} + +static int +smi_select(device_t dev, int op, int sleep) +{ + int err, i; + device_t iicbus = device_get_parent(dev); + struct iicbus_ivar *devi = IICBUS_IVAR(dev); + int slave = devi->addr; + + RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev)); + /* + * The chip does not use clock stretching when it is busy, + * instead ignoring the command. Retry a few times. + */ + for (i = RTL_IICBUS_RETRIES; i--; ) { + err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT); + if (err != IIC_ENOACK) + break; + if (sleep == RTL_WAITOK) { + DEBUG_INCRVAR(iic_select_retries); + pause("smi_select", RTL_IICBUS_RETRY_SLEEP); + } else + break; + } + return (err); +} + +static int +smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep) +{ + int err; + device_t iicbus = device_get_parent(sc->dev); + char bytes[2]; + int xferd; + + RTL_SMI_ACQUIRED_ASSERT(sc); + bytes[0] = addr & 0xff; + bytes[1] = (addr >> 8) & 0xff; + err = smi_select(sc->dev, RTL_IICBUS_READ, sleep); + if (err != 0) + goto out; + err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT); + if (err != 0) + goto out; + err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0); + if (err != 0) + goto out; + *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff); + +out: + iicbus_stop(iicbus); + return (err); +} + +static int +smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep) +{ + int err; + device_t iicbus = device_get_parent(sc->dev); + char bytes[4]; + int xferd; + + RTL_SMI_ACQUIRED_ASSERT(sc); + bytes[0] = addr & 0xff; + bytes[1] = (addr >> 8) & 0xff; + bytes[2] = data & 0xff; + bytes[3] = (data >> 8) & 0xff; + + err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep); + if (err == 0) + err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT); + iicbus_stop(iicbus); + + return (err); +} + +static int +smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + int err; + + err = smi_acquire(sc, sleep); + if (err != 0) + return (EBUSY); + err = smi_read_locked(sc, addr, data, sleep); + smi_release(sc, sleep); + DEVERR(dev, err, "smi_read()=%d: addr=%04x\n", addr); + return (err == 0 ? 0 : EIO); +} + +static int +smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + int err; + + err = smi_acquire(sc, sleep); + if (err != 0) + return (EBUSY); + err = smi_write_locked(sc, addr, data, sleep); + smi_release(sc, sleep); + DEVERR(dev, err, "smi_write()=%d: addr=%04x\n", addr); + return (err == 0 ? 0 : EIO); +} + +static int +smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + int err; + uint16_t oldv, newv; + + err = smi_acquire(sc, sleep); + if (err != 0) + return (EBUSY); + if (err == 0) { + err = smi_read_locked(sc, addr, &oldv, sleep); + if (err == 0) { + newv = oldv & ~mask; + newv |= data & mask; + if (newv != oldv) + err = smi_write_locked(sc, addr, newv, sleep); + } + } + smi_release(sc, sleep); + DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr); + return (err == 0 ? 0 : EIO); +} + +static etherswitch_info_t * +rtl_getinfo(device_t dev) +{ + return (ðerswitch_info); +} + +static int +rtl_readreg(device_t dev, int reg) +{ + uint16_t data = 0; + + smi_read(dev, reg, &data, RTL_WAITOK); + return (data); +} + +static int +rtl_writereg(device_t dev, int reg, int value) +{ + return (smi_write(dev, reg, value, RTL_WAITOK)); +} + +static int +rtl_getport(device_t dev, etherswitch_port_t *p) +{ + struct rtl8366rb_softc *sc; + struct ifmedia *ifm; + struct mii_data *mii; + struct ifmediareq *ifmr = &p->es_ifmr; + uint16_t v; + int err; + + if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS) + return (ENXIO); + p->es_vlangroup = RTL8366RB_PVCR_GET(p->es_port, + rtl_readreg(dev, RTL8366RB_PVCR_REG(p->es_port))); + + if (p->es_port < RTL8366RB_NUM_PHYS) { + sc = device_get_softc(dev); + mii = device_get_softc(sc->miibus[p->es_port]); + ifm = &mii->mii_media; + err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA); + if (err) + return (err); + } else { + /* fill in fixed values for CPU port */ + ifmr->ifm_count = 0; + smi_read(dev, RTL8366RB_PLSR_BASE + (RTL8366RB_NUM_PHYS)/2, &v, RTL_WAITOK); + v = v >> (8 * ((RTL8366RB_NUM_PHYS) % 2)); + rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active); + ifmr->ifm_current = ifmr->ifm_active; + ifmr->ifm_mask = 0; + ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; + } + return (0); +} + +static int +rtl_setport(device_t dev, etherswitch_port_t *p) +{ + int err; + struct rtl8366rb_softc *sc; + struct ifmedia *ifm; + struct mii_data *mii; + + if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS) + return (ENXIO); + err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port), + RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK), + RTL8366RB_PVCR_VAL(p->es_port, p->es_vlangroup), RTL_WAITOK); + if (err) + return (err); + sc = device_get_softc(dev); + mii = device_get_softc(sc->miibus[p->es_port]); + ifm = &mii->mii_media; + err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA); + return (err); +} + +static int +rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ + uint16_t vmcr[3]; + int i; + + for (i=0; i<3; i++) + vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup)); + + vg->es_vid = RTL8366RB_VMCR_VID(vmcr); + vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr); + vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr); + vg->es_fid = RTL8366RB_VMCR_FID(vmcr); + return (0); +} + +static int +rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) +{ + int g = vg->es_vlangroup; + + rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g), + (vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK); + rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g), + ((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) | + ((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK)); + rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g), + vg->es_fid); + return (0); +} + +static int +rtl_readphy(device_t dev, int phy, int reg) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + uint16_t data = 0; + int err, i, sleep; + + if (phy < 0 || phy >= RTL8366RB_NUM_PHYS) + return (ENXIO); + if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG) + return (ENXIO); + sleep = RTL_WAITOK; + err = smi_acquire(sc, sleep); + if (err != 0) + return (EBUSY); + for (i = RTL_IICBUS_RETRIES; i--; ) { + err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep); + if (err == 0) + err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep); + if (err == 0) { + err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep); + break; + } + DEBUG_INCRVAR(phy_access_retries); + DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i); + pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP); + } + smi_release(sc, sleep); + DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg); + return (data); +} + +static int +rtl_writephy(device_t dev, int phy, int reg, int data) +{ + struct rtl8366rb_softc *sc = device_get_softc(dev); + int err, i, sleep; + + if (phy < 0 || phy >= RTL8366RB_NUM_PHYS) + return (ENXIO); + if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG) + return (ENXIO); + sleep = RTL_WAITOK; + err = smi_acquire(sc, sleep); + if (err != 0) + return (EBUSY); + for (i = RTL_IICBUS_RETRIES; i--; ) { + err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep); + if (err == 0) + err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep); + if (err == 0) { + break; + } + DEBUG_INCRVAR(phy_access_retries); + DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i); + pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP); + } + smi_release(sc, sleep); + DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg); + return (err == 0 ? 0 : EIO); +} + +static int +rtl8366rb_ifmedia_upd(struct ifnet *ifp) +{ + struct rtl8366rb_softc *sc = ifp->if_softc; + struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]); + + mii_mediachg(mii); + return (0); +} + +static void +rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct rtl8366rb_softc *sc = ifp->if_softc; + struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]); + + mii_pollstat(mii); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + + +static device_method_t rtl8366rb_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, rtl8366rb_identify), + DEVMETHOD(device_probe, rtl8366rb_probe), + DEVMETHOD(device_attach, rtl8366rb_attach), + DEVMETHOD(device_detach, rtl8366rb_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + + /* MII interface */ + DEVMETHOD(miibus_readreg, rtl_readphy), + DEVMETHOD(miibus_writereg, rtl_writephy), + + /* etherswitch interface */ + DEVMETHOD(etherswitch_getinfo, rtl_getinfo), + DEVMETHOD(etherswitch_readreg, rtl_readreg), + DEVMETHOD(etherswitch_writereg, rtl_writereg), + DEVMETHOD(etherswitch_readphyreg, rtl_readphy), + DEVMETHOD(etherswitch_writephyreg, rtl_writephy), + DEVMETHOD(etherswitch_getport, rtl_getport), + DEVMETHOD(etherswitch_setport, rtl_setport), + DEVMETHOD(etherswitch_getvgroup, rtl_getvgroup), + DEVMETHOD(etherswitch_setvgroup, rtl_setvgroup), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods, + sizeof(struct rtl8366rb_softc)); +static devclass_t rtl8366rb_devclass; + +DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0); +DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0); +DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0); +MODULE_VERSION(rtl8366rb, 1); +MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */ +MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */ +MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */ diff --git a/sys/dev/etherswitch/rtl8366rbvar.h b/sys/dev/etherswitch/rtl8366rbvar.h new file mode 100644 index 0000000..4f3d1ba --- /dev/null +++ b/sys/dev/etherswitch/rtl8366rbvar.h @@ -0,0 +1,176 @@ +/*- + * Copyright (c) 2011-2012 Stefan Bethke. + * 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 _DEV_ETHERSWITCH_RTL8366RBVAR_H_ +#define _DEV_ETHERSWITCH_RTL8366RBVAR_H_ + +#define RTL8366RB_IIC_ADDR 0xa8 +#define RTL_IICBUS_TIMEOUT 100 /* us */ +#define RTL_IICBUS_READ 1 +#define RTL_IICBUS_WRITE 0 +/* number of times to try and select the chip on the I2C bus */ +#define RTL_IICBUS_RETRIES 3 +#define RTL_IICBUS_RETRY_SLEEP (hz/1000) + +/* Register definitions */ + +/* Switch Global Configuration */ +#define RTL8366RB_SGCR 0x0000 +#define RTL8366RB_SGCR_EN_BC_STORM_CTRL 0x0001 +#define RTL8366RB_SGCR_MAX_LENGTH_MASK 0x0030 +#define RTL8366RB_SGCR_MAX_LENGTH_1522 0x0000 +#define RTL8366RB_SGCR_MAX_LENGTH_1536 0x0010 +#define RTL8366RB_SGCR_MAX_LENGTH_1552 0x0020 +#define RTL8366RB_SGCR_MAX_LENGTH_9216 0x0030 +#define RTL8366RB_SGCR_EN_VLAN 0x2000 +#define RTL8366RB_SGCR_EN_VLAN_4KTB 0x4000 +#define RTL8366RB_SGCR_EN_QOS 0x8000 + +/* Port Enable Control: DISABLE_PORT[5:0] */ +#define RTL8366RB_PECR 0x0001 + +/* Switch Security Control 0: DIS_LEARN[5:0] */ +#define RTL8366RB_SSCR0 0x0002 + +/* Switch Security Control 1: DIS_AGE[5:0] */ +#define RTL8366RB_SSCR1 0x0003 + +/* Switch Security Control 2 */ +#define RTL8366RB_SSCR2 0x0004 +#define RTL8366RB_SSCR2_DROP_UNKNOWN_DA 0x0001 + +/* Port Link Status: two ports per register */ +#define RTL8366RB_PLSR_BASE 0x0014 +#define RTL8366RB_PLSR_SPEED_MASK 0x03 +#define RTL8366RB_PLSR_SPEED_10 0x00 +#define RTL8366RB_PLSR_SPEED_100 0x01 +#define RTL8366RB_PLSR_SPEED_1000 0x02 +#define RTL8366RB_PLSR_FULLDUPLEX 0x08 +#define RTL8366RB_PLSR_LINK 0x10 +#define RTL8366RB_PLSR_TXPAUSE 0x20 +#define RTL8366RB_PLSR_RXPAUSE 0x40 +#define RTL8366RB_PLSR_NO_AUTO 0x80 + +/* VLAN Member Configuration, 3 registers per VLAN */ +#define RTL8366RB_VMCR_BASE 0x0020 +#define RTL8366RB_VMCR_MULT 3 +#define RTL8366RB_VMCR_DOT1Q_REG 0 +#define RTL8366RB_VMCR_DOT1Q_VID_SHIFT 0 +#define RTL8366RB_VMCR_DOT1Q_VID_MASK 0x0fff +#define RTL8366RB_VMCR_DOT1Q_PCP_SHIFT 12 +#define RTL8366RB_VMCR_DOT1Q_PCP_MASK 0x7000 +#define RTL8366RB_VMCR_MU_REG 1 +#define RTL8366RB_VMCR_MU_MEMBER_SHIFT 0 +#define RTL8366RB_VMCR_MU_MEMBER_MASK 0x00ff +#define RTL8366RB_VMCR_MU_UNTAG_SHIFT 8 +#define RTL8366RB_VMCR_MU_UNTAG_MASK 0xff00 +#define RTL8366RB_VMCR_FID_REG 2 +#define RTL8366RB_VMCR_FID_FID_SHIFT 0 +#define RTL8366RB_VMCR_FID_FID_MASK 0x0007 +#define RTL8366RB_VMCR(_reg, _vlan) \ + (RTL8366RB_VMCR_BASE + _reg + _vlan * RTL8366RB_VMCR_MULT) +/* VLAN Identifier */ +#define RTL8366RB_VMCR_VID(_r) \ + (_r[RTL8366RB_VMCR_DOT1Q_REG] & RTL8366RB_VMCR_DOT1Q_VID_MASK) +/* Priority Code Point */ +#define RTL8366RB_VMCR_PCP(_r) \ + ((_r[RTL8366RB_VMCR_DOT1Q_REG] & RTL8366RB_VMCR_DOT1Q_PCP_MASK) \ + >> RTL8366RB_VMCR_DOT1Q_PCP_SHIFT) +/* Member ports */ +#define RTL8366RB_VMCR_MEMBER(_r) \ + (_r[RTL8366RB_VMCR_MU_REG] & RTL8366RB_VMCR_MU_MEMBER_MASK) +/* Untagged ports */ +#define RTL8366RB_VMCR_UNTAG(_r) \ + ((_r[RTL8366RB_VMCR_MU_REG] & RTL8366RB_VMCR_MU_UNTAG_MASK) \ + >> RTL8366RB_VMCR_MU_UNTAG_SHIFT) +/* Forwarding ID */ +#define RTL8366RB_VMCR_FID(_r) \ + (_r[RTL8366RB_VMCR_FID_REG] & RTL8366RB_VMCR_FID_FID_MASK) + +/* + * Port VLAN Control, 4 ports per register + * Determines the VID for untagged ingress frames through + * index into VMC. + */ +#define RTL8366RB_PVCR_BASE 0x0063 +#define RTL8366RB_PVCR_PORT_SHIFT 4 +#define RTL8366RB_PVCR_PORT_PERREG (16 / RTL8366RB_PVCR_PORT_SHIFT) +#define RTL8366RB_PVCR_PORT_MASK 0x000f +#define RTL8366RB_PVCR_REG(_port) \ + (RTL8366RB_PVCR_BASE + _port / (RTL8366RB_PVCR_PORT_PERREG)) +#define RTL8366RB_PVCR_VAL(_port, _pvlan) \ + ((_pvlan & RTL8366RB_PVCR_PORT_MASK) << \ + ((_port % RTL8366RB_PVCR_PORT_PERREG) * RTL8366RB_PVCR_PORT_SHIFT)) +#define RTL8366RB_PVCR_GET(_port, _val) \ + (((_val) >> ((_port % RTL8366RB_PVCR_PORT_PERREG) * RTL8366RB_PVCR_PORT_SHIFT)) & RTL8366RB_PVCR_PORT_MASK) + +/* Reset Control */ +#define RTL8366RB_RCR 0x0100 +#define RTL8366RB_RCR_HARD_RESET 0x0001 +#define RTL8366RB_RCR_SOFT_RESET 0x0002 + +/* Chip Version Control: CHIP_VER[3:0] */ +#define RTL8366RB_CVCR 0x050A +/* Chip Identifier */ +#define RTL8366RB_CIR 0x0509 +#define RTL8366RB_CIR_ID8366RB 0x5937 + +/* VLAN Ingress Control 2: [5:0] */ +#define RTL8366RB_VIC2R 0x037f + +/* MIB registers */ +#define RTL8366RB_MCNT_BASE 0x1000 +#define RTL8366RB_MCTLR 0x13f0 +#define RTL8366RB_MCTLR_BUSY 0x0001 +#define RTL8366RB_MCTLR_RESET 0x0002 +#define RTL8366RB_MCTLR_RESET_PORT_MASK 0x00fc +#define RTL8366RB_MCTLR_RESET_ALL 0x0800 + +#define RTL8366RB_MCNT(_port, _r) \ + (RTL8366RB_MCNT_BASE + 0x50 * (_port) + (_r)) +#define RTL8366RB_MCTLR_RESET_PORT(_p) \ + (1 << ((_p) + 2)) + +/* PHY Access Control */ +#define RTL8366RB_PACR 0x8000 +#define RTL8366RB_PACR_WRITE 0x0000 +#define RTL8366RB_PACR_READ 0x0001 + +/* PHY Access Data */ +#define RTL8366RB_PADR 0x8002 + +#define RTL8366RB_PHYREG(phy, page, reg) \ + (RTL8366RB_PACR | (1 << (((phy) & 0x1f) + 9)) | (((page) & 0xf) << 5) | ((reg) & 0x1f)) + +/* general characteristics of the chip */ +#define RTL8366RB_NUM_PORTS 6 +#define RTL8366RB_NUM_PHYS (RTL8366RB_NUM_PORTS-1) +#define RTL8366RB_NUM_VLANS 16 +#define RTL8366RB_NUM_PHY_REG 32 + +#endif diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c index d5c2270..caaf963 100644 --- a/sys/dev/flash/mx25l.c +++ b/sys/dev/flash/mx25l.c @@ -101,7 +101,9 @@ struct mx25l_flash_ident flash_devices[] = { { "mx25ll64", 0xc2, 0x2017, 64 * 1024, 128, FL_NONE }, { "mx25ll128", 0xc2, 0x2018, 64 * 1024, 256, FL_ERASE_4K | FL_ERASE_32K }, { "s25fl128", 0x01, 0x2018, 64 * 1024, 256, FL_NONE }, + { "s25sl032", 0x01, 0x0215, 64 * 1024, 64, FL_NONE }, { "s25sl064a", 0x01, 0x0216, 64 * 1024, 128, FL_NONE }, + { "w25q64bv", 0xef, 0x4017, 64 * 1024, 128, FL_ERASE_4K }, }; static uint8_t diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index a2f6163..a682034 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -360,8 +362,7 @@ apb_intr(void *arg) continue; } - /* TODO: frame instead of NULL? */ - intr_event_handle(event, NULL); + intr_event_handle(event, curthread->td_intr_frame); mips_intrcnt_inc(sc->sc_intr_counter[irq]); } } diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index 592cd2b..9639d1f 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -329,7 +329,7 @@ ar71xx_gpio_attach(device_t dev) struct ar71xx_gpio_softc *sc = device_get_softc(dev); int error = 0; int i, j, maxpin; - int mask; + int mask, pinon; int old = 0; KASSERT((device_get_unit(dev) == 0), @@ -394,6 +394,9 @@ ar71xx_gpio_attach(device_t dev) if (resource_int_value(device_get_name(dev), device_get_unit(dev), "pinmask", &mask) != 0) mask = 0; + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "pinon", &pinon) != 0) + pinon = 0; device_printf(dev, "gpio pinmask=0x%x\n", mask); for (i = 0, j = 0; j < maxpin; j++) { if ((mask & (1 << j)) == 0) @@ -407,6 +410,11 @@ ar71xx_gpio_attach(device_t dev) i++; } sc->gpio_npins = i; + for (i = 0; i < sc->gpio_npins; i++) { + j = sc->gpio_pins[i].gp_pin; + if ((pinon & (1 << j)) != 0) + ar71xx_gpio_pin_set(dev, j, 1); + } device_add_child(dev, "gpioc", device_get_unit(dev)); device_add_child(dev, "gpiobus", device_get_unit(dev)); return (bus_generic_attach(dev)); diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index a6c7c1b..38d5adb 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -503,8 +505,7 @@ ar71xx_pci_intr(void *arg) /* Flush DDR FIFO for IP2 */ ar71xx_device_ddr_flush_ip2(); - /* TODO: frame instead of NULL? */ - intr_event_handle(event, NULL); + intr_event_handle(event, curthread->td_intr_frame); mips_intrcnt_inc(sc->sc_intr_counter[irq]); } } diff --git a/sys/mips/atheros/ar71xx_pmc.c b/sys/mips/atheros/ar71xx_pmc.c new file mode 100644 index 0000000..fc6bb08 --- /dev/null +++ b/sys/mips/atheros/ar71xx_pmc.c @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2011, 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 unmodified, 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. + */ + +/* + * Tie into the PMC interrupt line and call the HWPMC hooks as needed. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct ar71xx_pmc_softc { + device_t dev; + struct resource * pmc_irq; + void * pmc_intrhand; +}; + +static int +ar71xx_pmc_probe(device_t dev) +{ + + device_set_desc(dev, "Atheros AR71XX PMC interrupt device"); + return (0); +} + +static int +ar71xx_pmc_intr_filter(void *arg) +{ + struct trapframe *tf = curthread->td_intr_frame; + + printf("%s: called; tf=%p\n", __func__, tf); + if (pmc_intr && (*pmc_intr)(PCPU_GET(cpuid), tf) == 1) { + return (FILTER_HANDLED); + } + printf("%s: stray\n", __func__); + return (FILTER_STRAY); +} + +static int +ar71xx_pmc_attach(device_t dev) +{ + struct ar71xx_pmc_softc *sc = device_get_softc(dev); + int rid, error; + + sc->dev = dev; + rid = 0; + sc->pmc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (sc->pmc_irq == NULL) { + device_printf(dev, "%s: couldn't allocate IRQ\n", __func__); + return ENXIO; + } + + /* XXX INTR_TYPE_NET? */ + error = bus_setup_intr(dev, sc->pmc_irq, INTR_TYPE_NET | INTR_MPSAFE, + ar71xx_pmc_intr_filter, NULL, sc, &sc->pmc_intrhand); + + return (0); +} + +static int +ar71xx_pmc_detach(device_t dev) +{ + struct ar71xx_pmc_softc *sc = device_get_softc(dev); + + if (sc->pmc_intrhand) + bus_teardown_intr(dev, sc->pmc_irq, sc->pmc_intrhand); + + return (0); +} + +static device_method_t ar71xx_pmc_methods[] = { + DEVMETHOD(device_probe, ar71xx_pmc_probe), + DEVMETHOD(device_attach, ar71xx_pmc_attach), + DEVMETHOD(device_detach, ar71xx_pmc_detach), + {0, 0}, +}; + +static driver_t ar71xx_pmc_driver = { + "ar71xx_pmc", + ar71xx_pmc_methods, + sizeof(struct ar71xx_pmc_softc), +}; +static devclass_t ar71xx_pmc_devclass; + +DRIVER_MODULE(ar71xx_pmc, apb, ar71xx_pmc_driver, ar71xx_pmc_devclass, 0, 0); diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index da5fc5d..c4d0bfd 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -272,10 +272,6 @@ */ #define AR71XX_MAC0_BASE 0x19000000 #define AR71XX_MAC1_BASE 0x1A000000 -/* - * All 5 PHYs accessible only through MAC0 register space - */ -#define AR71XX_MII_BASE 0x19000000 #define AR71XX_MAC_CFG1 0x00 #define MAC_CFG1_SOFT_RESET (1 << 31) diff --git a/sys/mips/atheros/ar724x_pci.c b/sys/mips/atheros/ar724x_pci.c index 59be9c0..7098e9e 100644 --- a/sys/mips/atheros/ar724x_pci.c +++ b/sys/mips/atheros/ar724x_pci.c @@ -542,8 +542,7 @@ ar724x_pci_intr(void *arg) return (FILTER_STRAY); } - /* TODO: frame instead of NULL? */ - intr_event_handle(event, NULL); + intr_event_handle(event, curthread->td_intr_frame); mips_intrcnt_inc(sc->sc_intr_counter[irq]); } diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index b0b7b02..941d354 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -21,3 +21,4 @@ mips/atheros/ar71xx_setup.c standard mips/atheros/ar71xx_chip.c standard mips/atheros/ar724x_chip.c standard mips/atheros/ar91xx_chip.c standard +mips/atheros/ar71xx_pmc.c optional ar71xx_pmc hwpmc diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 0154ae2..3dd2e15 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -72,8 +72,18 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#if defined(ARGE_MDIO) +#include +#include +#include "mdio_if.h" +#endif + + MODULE_DEPEND(arge, ether, 1, 1, 1); MODULE_DEPEND(arge, miibus, 1, 1, 1); +MODULE_VERSION(arge, 1); #include "miibus_if.h" @@ -102,6 +112,7 @@ typedef enum { #endif static int arge_attach(device_t); +static int arge_attach_finish(struct arge_softc *sc); static int arge_detach(device_t); static void arge_flush_ddr(struct arge_softc *); static int arge_ifmedia_upd(struct ifnet *); @@ -134,6 +145,8 @@ static void arge_intr(void *); static int arge_intr_filter(void *); static void arge_tick(void *); +static void arge_hinted_child(device_t bus, const char *dname, int dunit); + /* * ifmedia callbacks for multiPHY MAC */ @@ -160,6 +173,10 @@ static device_method_t arge_methods[] = { DEVMETHOD(miibus_writereg, arge_miibus_writereg), DEVMETHOD(miibus_statchg, arge_miibus_statchg), + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + DEVMETHOD(bus_hinted_child, arge_hinted_child), + DEVMETHOD_END }; @@ -174,6 +191,37 @@ static devclass_t arge_devclass; DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0); DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); +#if defined(ARGE_MDIO) +static int argemdio_probe(device_t); +static int argemdio_attach(device_t); +static int argemdio_detach(device_t); + +/* + * Declare an additional, separate driver for accessing the MDIO bus. + */ +static device_method_t argemdio_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, argemdio_probe), + DEVMETHOD(device_attach, argemdio_attach), + DEVMETHOD(device_detach, argemdio_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, device_add_child_ordered), + + /* MDIO access */ + DEVMETHOD(mdio_readreg, arge_miibus_readreg), + DEVMETHOD(mdio_writereg, arge_miibus_writereg), +}; + +DEFINE_CLASS_0(argemdio, argemdio_driver, argemdio_methods, + sizeof(struct arge_softc)); +static devclass_t argemdio_devclass; + +DRIVER_MODULE(miiproxy, arge, miiproxy_driver, miiproxy_devclass, 0, 0); +DRIVER_MODULE(argemdio, nexus, argemdio_driver, argemdio_devclass, 0, 0); +DRIVER_MODULE(mdio, argemdio, mdio_driver, mdio_devclass, 0, 0); +#endif + /* * RedBoot passes MAC address to entry point as environment * variable. platfrom_start parses it and stores in this variable @@ -234,15 +282,22 @@ arge_attach_sysctl(device_t dev) #endif } +#if defined(ARGE_MDIO) +static void +arge_attach_proxy(void *aa) +{ + arge_attach_finish(aa); +} +#endif + static int arge_attach(device_t dev) { - uint8_t eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; struct arge_softc *sc; - int error = 0, rid, phymask; + int error = 0, rid; uint32_t reg, rnd; - int is_base_mac_empty, i, phys_total; + int is_base_mac_empty, i; uint32_t hint; long eeprom_mac_addr = 0; @@ -277,18 +332,18 @@ arge_attach(device_t dev) * Get which PHY of 5 available we should use for this unit */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "phymask", &phymask) != 0) { + "phymask", &sc->arge_phymask) != 0) { /* * Use port 4 (WAN) for GE0. For any other port use * its PHY the same as its unit number */ if (sc->arge_mac_unit == 0) - phymask = (1 << 4); + sc->arge_phymask = (1 << 4); else /* Use all phys up to 4 */ - phymask = (1 << 4) - 1; + sc->arge_phymask = (1 << 4) - 1; - device_printf(dev, "No PHY specified, using mask %d\n", phymask); + device_printf(dev, "No PHY specified, using mask %d\n", sc->arge_phymask); } /* @@ -313,8 +368,6 @@ arge_attach(device_t dev) else sc->arge_duplex_mode = 0; - sc->arge_phymask = phymask; - mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0); @@ -323,7 +376,7 @@ arge_attach(device_t dev) /* Map control/status registers. */ sc->arge_rid = 0; sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->arge_rid, RF_ACTIVE); + &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE); if (sc->arge_res == NULL) { device_printf(dev, "couldn't map memory\n"); @@ -371,8 +424,8 @@ arge_attach(device_t dev) is_base_mac_empty = 1; for (i = 0; i < ETHER_ADDR_LEN; i++) { - eaddr[i] = ar711_base_mac[i] & 0xff; - if (eaddr[i] != 0) + sc->arge_eaddr[i] = ar711_base_mac[i] & 0xff; + if (sc->arge_eaddr[i] != 0) is_base_mac_empty = 0; } @@ -385,16 +438,15 @@ arge_attach(device_t dev) "Generating random ethernet address.\n"); rnd = arc4random(); - eaddr[0] = 'b'; - eaddr[1] = 's'; - eaddr[2] = 'd'; - eaddr[3] = (rnd >> 24) & 0xff; - eaddr[4] = (rnd >> 16) & 0xff; - eaddr[5] = (rnd >> 8) & 0xff; + sc->arge_eaddr[0] = 'b'; + sc->arge_eaddr[1] = 's'; + sc->arge_eaddr[2] = 'd'; + sc->arge_eaddr[3] = (rnd >> 24) & 0xff; + sc->arge_eaddr[4] = (rnd >> 16) & 0xff; + sc->arge_eaddr[5] = (rnd >> 8) & 0xff; } - if (sc->arge_mac_unit != 0) - eaddr[5] += sc->arge_mac_unit; + sc->arge_eaddr[5] += sc->arge_mac_unit; if (arge_dma_alloc(sc) != 0) { error = ENXIO; @@ -423,19 +475,23 @@ arge_attach(device_t dev) ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536); +#if !defined(ARGE_MDIO) /* Reset MII bus */ ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); DELAY(100); ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); DELAY(100); +#endif /* * Set all Ethernet address registers to the same initial values * set all four addresses to 66-88-aa-cc-dd-ee */ - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, - (eaddr[2] << 24) | (eaddr[3] << 16) | (eaddr[4] << 8) | eaddr[5]); - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (eaddr[0] << 8) | eaddr[1]); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, (sc->arge_eaddr[2] << 24) + | (sc->arge_eaddr[3] << 16) | (sc->arge_eaddr[4] << 8) + | sc->arge_eaddr[5]); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (sc->arge_eaddr[0] << 8) + | sc->arge_eaddr[1]); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0, FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT); @@ -458,30 +514,44 @@ arge_attach(device_t dev) ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, FIFO_RX_FILTMASK_DEFAULT); - /* - * Check if we have single-PHY MAC or multi-PHY - */ - phys_total = 0; - for (i = 0; i < ARGE_NPHY; i++) - if (phymask & (1 << i)) - phys_total ++; +#if defined(ARGE_MDIO) + sc->arge_miiproxy = mii_attach_proxy(sc->arge_dev, arge_attach_proxy, sc); + if (sc->arge_miiproxy == NULL) + return (arge_attach_finish(sc)); +#else + return (arge_attach_finish(sc)); +#endif +fail: + if (error) + arge_detach(dev); - if (phys_total == 0) { - error = EINVAL; - goto fail; - } + return (error); +} - if (phys_total == 1) { - /* Do MII setup. */ - error = mii_attach(dev, &sc->arge_miibus, ifp, - arge_ifmedia_upd, arge_ifmedia_sts, BMSR_DEFCAPMASK, - MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; +static int +arge_attach_finish(struct arge_softc *sc) +{ + int error, phy; + + device_printf(sc->arge_dev, "finishing attachment, phymask %04x" + ", proxy %s \n", sc->arge_phymask, sc->arge_miiproxy == NULL ? + "null" : "set"); + for (phy = 0; phy < ARGE_NPHY; phy++) { + if (((1 << phy) & sc->arge_phymask) != 0) { + error = mii_attach(sc->arge_miiproxy != NULL ? + sc->arge_miiproxy : sc->arge_dev, + &sc->arge_miibus, sc->arge_ifp, + arge_ifmedia_upd, arge_ifmedia_sts, + BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + if (error != 0) { + device_printf(sc->arge_dev, "unable to attach" + " PHY %d: %d\n", phy, error); + goto fail; + } } } - else { + if (sc->arge_miibus == NULL) { + /* no PHY, so use hard-coded values */ ifmedia_init(&sc->arge_ifmedia, 0, arge_multiphy_mediachange, arge_multiphy_mediastatus); @@ -494,24 +564,23 @@ arge_attach(device_t dev) } /* Call MI attach routine. */ - ether_ifattach(ifp, eaddr); + ether_ifattach(sc->arge_ifp, sc->arge_eaddr); /* Hook interrupt last to avoid having to lock softc */ - error = bus_setup_intr(dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, + error = bus_setup_intr(sc->arge_dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, arge_intr_filter, arge_intr, sc, &sc->arge_intrhand); if (error) { - device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); + device_printf(sc->arge_dev, "couldn't set up irq\n"); + ether_ifdetach(sc->arge_ifp); goto fail; } /* setup sysctl variables */ - arge_attach_sysctl(dev); - + arge_attach_sysctl(sc->arge_dev); fail: if (error) - arge_detach(dev); + arge_detach(sc->arge_dev); return (error); } @@ -542,6 +611,9 @@ arge_detach(device_t dev) if (sc->arge_miibus) device_delete_child(dev, sc->arge_miibus); + if (sc->arge_miiproxy) + device_delete_child(dev, sc->arge_miiproxy); + bus_generic_detach(dev); if (sc->arge_intrhand) @@ -592,6 +664,13 @@ arge_shutdown(device_t dev) return (0); } +static void +arge_hinted_child(device_t bus, const char *dname, int dunit) +{ + BUS_ADD_CHILD(bus, 0, dname, dunit); + device_printf(bus, "hinted child %s%d\n", dname, dunit); +} + static int arge_miibus_readreg(device_t dev, int phy, int reg) { @@ -600,16 +679,13 @@ arge_miibus_readreg(device_t dev, int phy, int reg) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - if ((sc->arge_phymask & (1 << phy)) == 0) - return (0); - mtx_lock(&miibus_mtx); - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); - ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); i = ARGE_MII_TIMEOUT; - while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); @@ -620,8 +696,8 @@ arge_miibus_readreg(device_t dev, int phy, int reg) return (-1); } - result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; - ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); mtx_unlock(&miibus_mtx); ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, @@ -638,19 +714,15 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - - if ((sc->arge_phymask & (1 << phy)) == 0) - return (-1); - ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value=%04x\n", __func__, phy, reg, data); mtx_lock(&miibus_mtx); - ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); - ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); i = ARGE_MII_TIMEOUT; - while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); @@ -715,6 +787,8 @@ arge_set_pll(struct arge_softc *sc, int media, int duplex) uint32_t fifo_tx; int if_speed; + ARGEDEBUG(sc, ARGE_DBG_MII, "set_pll(%04x, %s)\n", media, + duplex == IFM_FDX ? "full" : "half"); cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); cfg &= ~(MAC_CFG2_IFACE_MODE_1000 | MAC_CFG2_IFACE_MODE_10_100 @@ -1923,3 +1997,47 @@ arge_multiphy_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) sc->arge_duplex_mode; } +#if defined(ARGE_MDIO) +static int +argemdio_probe(device_t dev) +{ + device_set_desc(dev, "Atheros AR71xx built-in ethernet interface, MDIO controller"); + return (0); +} + +static int +argemdio_attach(device_t dev) +{ + struct arge_softc *sc; + int error = 0; + + sc = device_get_softc(dev); + sc->arge_dev = dev; + sc->arge_mac_unit = device_get_unit(dev); + sc->arge_rid = 0; + sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE); + if (sc->arge_res == NULL) { + device_printf(dev, "couldn't map memory\n"); + error = ENXIO; + goto fail; + } + /* Reset MII bus */ + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); + DELAY(100); + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); + DELAY(100); + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + error = bus_generic_attach(dev); +fail: + return (error); +} + +static int +argemdio_detach(device_t dev) +{ + return (0); +} + +#endif diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index c1df678..dc3d931 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -67,15 +67,10 @@ #define ARGE_CLEAR_BITS(sc, reg, bits) \ ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) -/* - * MII registers access macros - */ -#define ARGE_MII_READ(reg) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) - -#define ARGE_MII_WRITE(reg, val) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) = (val) - +#define ARGE_MDIO_WRITE(_sc, _reg, _val) \ + ARGE_WRITE((_sc), (_reg), (_val)) +#define ARGE_MDIO_READ(_sc, _reg) \ + ARGE_READ((_sc), (_reg)) #define ARGE_DESC_EMPTY (1 << 31) #define ARGE_DESC_MORE (1 << 24) @@ -132,11 +127,14 @@ struct arge_softc { */ uint32_t arge_media_type; uint32_t arge_duplex_mode; + uint32_t arge_phymask; + uint8_t arge_eaddr[ETHER_ADDR_LEN]; struct resource *arge_res; int arge_rid; struct resource *arge_irq; void *arge_intrhand; device_t arge_miibus; + device_t arge_miiproxy; bus_dma_tag_t arge_parent_tag; bus_dma_tag_t arge_tag; struct mtx arge_mtx; @@ -148,7 +146,6 @@ struct arge_softc { int arge_detach; uint32_t arge_intr_status; int arge_mac_unit; - int arge_phymask; int arge_if_flags; uint32_t arge_debug; struct { diff --git a/sys/mips/conf/AR91XX_BASE b/sys/mips/conf/AR91XX_BASE index a3686be..ba44bcf 100644 --- a/sys/mips/conf/AR91XX_BASE +++ b/sys/mips/conf/AR91XX_BASE @@ -16,6 +16,7 @@ cpu CPU_MIPS4KC options ISA_MIPS32 makeoptions KERNLOADADDR=0x80050000 options HZ=1000 +options HWPMC_HOOKS files "../atheros/files.ar71xx" hints "AR91XX_BASE.hints" @@ -111,3 +112,9 @@ device random device if_bridge device gpio device gpioled +device vlan + +device hwpmc + +# Tie into the interrupt line for PMC events +device ar71xx_pmc diff --git a/sys/mips/conf/AR91XX_BASE.hints b/sys/mips/conf/AR91XX_BASE.hints index 81442f3..b911d49 100644 --- a/sys/mips/conf/AR91XX_BASE.hints +++ b/sys/mips/conf/AR91XX_BASE.hints @@ -57,3 +57,6 @@ hint.gpio.0.at="apb0" hint.gpio.0.maddr=0x18040000 hint.gpio.0.msize=0x1000 hint.gpio.0.irq=2 + +hint.ar71xx_pmc.0.at="apb0" +hint.ar71xx_pmc.0.irq=5 diff --git a/sys/mips/conf/TL-MR3420 b/sys/mips/conf/TL-MR3420 new file mode 100644 index 0000000..6f89f31 --- /dev/null +++ b/sys/mips/conf/TL-MR3420 @@ -0,0 +1,45 @@ +# +# TL-WR3420 -- Kernel configuration file for the TP-Link MR3420 +# +# $FreeBSD$ +# + +# Include the default AR913x parameters common to all AR913x SoC users. +include "AR91XX_BASE" + +ident TL-MR3420 + +# Override hints with board values +hints "TL-MR3420.hints" + +# Force the board memory - 32mb +options AR71XX_REALMEM=32*1024*1024 + +nodevice ath +nodevice ath_rate_sample +nodevice ath_ahb +nodevice ath_ar5212 +nodevice ath_ar5416 +nodevice ath_ar9130 +nodevice ath_rf5111 + +# ethernet switch device +device etherswitch +device arswitch +device miiproxy +options ARGE_MDIO + +# Enable the uboot environment stuff rather then the +# redboot stuff. +options AR71XX_ENV_UBOOT + +# uzip - to boot natively from flash +device geom_uzip +options GEOM_UZIP + +# Used for the static uboot partition map +device geom_map + +# Boot off of the rootfs, as defined in the geom_map setup. +options ROOTDEVNAME=\"ufs:map/rootfs.uzip\" +options ROOTDEVNAME=\"ufs:da0s1a\" diff --git a/sys/mips/conf/TL-MR3420.hints b/sys/mips/conf/TL-MR3420.hints new file mode 100644 index 0000000..58adf3f --- /dev/null +++ b/sys/mips/conf/TL-MR3420.hints @@ -0,0 +1,95 @@ +# +# This file adds to the values in AR91XX_BASE.hints. +# +# $FreeBSD$ + +# AR7241 has built in switch and hardwired MAC connections, so just supply +# the appropriate values. +hint.arge.0.phymask=0x10 +hint.arge.0.eeprommac=0x1f01fc00 +hint.arge.0.mdio=mdioproxy1 + +hint.arge.1.phymask=0 +hint.arge.1.media=1000 +hint.arge.1.fduplex=1 + +# MDIO bus of arge0 is unused, MDIO bus of arge1 is used to talk to switch +hint.argemdio.0.at="nexus0" +hint.argemdio.0.maddr=0x1A000000 +hint.argemdio.0.msize=0x1000 + +# Where the ART is +#hint.ath.0.eepromaddr=0x1fff1000 + +# from uboot: +# mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),2752k(rootfs),896k(uImage),64k(NVRAM),64k(ART) + +hint.map.0.at="flash/spi0" +hint.map.0.start=0x00000000 +hint.map.0.end=0x00040000 +hint.map.0.name="uboot" +hint.map.0.readonly=1 + +hint.map.1.at="flash/spi0" +hint.map.1.start=0x00004000 +hint.map.1.end=0x00050000 +hint.map.1.name="ubootenv" +hint.map.1.readonly=1 + +hint.map.2.at="flash/spi0" +hint.map.2.start=0x00060000 +hint.map.2.end=0x00300000 +hint.map.2.name="rootfs" +hint.map.2.readonly=1 + +hint.map.3.at="flash/spi0" +hint.map.3.start=0x00300000 +hint.map.3.end=0x003e00000 +hint.map.3.name="uimage" +hint.map.3.readonly=0 + +hint.map.3.at="flash/spi0" +hint.map.3.start=0x003e0000 +hint.map.3.end=0x003f0000 +hint.map.3.name="nvram" +hint.map.3.readonly=0 + +hint.map.5.at="flash/spi0" +hint.map.5.start=0x003f0000 +hint.map.5.end=0x00800000 +hint.map.5.name="art" +hint.map.5.readonly=1 + +# GPIO specific configuration block + +# Don't flip on anything that isn't already enabled. +# This includes leaving the SPI CS1/CS2 pins as GPIO pins as they're +# not used here. +hint.gpio.0.function_set=0x00000000 +hint.gpio.0.function_clear=0x00000000 + +# These are the GPIO LEDs and buttons which can be software controlled. +hint.gpio.0.pinmask=0x1943 +# Switch on GPIO 6 to power up the USB port from the beginning +hint.gpio.0.pinon=0x0040 + +# Pin 0 - QSS (LED) +# Pin 1 - System (LED) +# Pin 6 - USB power (output) +# pin 8 - 3G (LED) +# Pin 11 - Reset (input) +# Pin 12 - QSS Button (input) + +# LEDs are configured separately and driven by the LED device +hint.gpioled.0.at="gpiobus0" +hint.gpioled.0.name="qss" +hint.gpioled.0.pins=0x0001 + +hint.gpioled.1.at="gpiobus0" +hint.gpioled.1.name="system" +hint.gpioled.1.pins=0x0002 + +hint.gpioled.2.at="gpiobus0" +hint.gpioled.2.name="3g" +hint.gpioled.2.pins=0x0008 + diff --git a/sys/mips/conf/TP-WN1043ND b/sys/mips/conf/TP-WN1043ND index d81a6f6..c05b870 100644 --- a/sys/mips/conf/TP-WN1043ND +++ b/sys/mips/conf/TP-WN1043ND @@ -15,6 +15,18 @@ hints "TP-WN1043ND.hints" # Force the board memory - 32mb options AR71XX_REALMEM=32*1024*1024 +# i2c GPIO bus +device gpioiic +device iicbb +device iicbus +device iic + +# ethernet switch device +device etherswitch + +# RTL8366RB support +device rtl8366rb + # read MSDOS formatted disks - USB options MSDOSFS options GEOM_PART_BSD diff --git a/sys/mips/conf/TP-WN1043ND.hints b/sys/mips/conf/TP-WN1043ND.hints index dce3fea..f72f3ce 100644 --- a/sys/mips/conf/TP-WN1043ND.hints +++ b/sys/mips/conf/TP-WN1043ND.hints @@ -81,7 +81,7 @@ hint.map.4.readonly=1 # Don't flip on anything that isn't already enabled. # This includes leaving the SPI CS1/CS2 pins as GPIO pins as they're # not used here. -hint.gpio.0.function_set=0x00000000 +hint.gpio.0.function_set=0x00002000 hint.gpio.0.function_clear=0x00000000 # These are the GPIO LEDs and buttons which can be software controlled. @@ -101,9 +101,9 @@ hint.gpio.0.pinmask=0x001c02ae # Pin 20 - "GPIO20" # LEDs are configured separately and driven by the LED device -hint.gpioled.0.at="gpiobus0" -hint.gpioled.0.name="usb" -hint.gpioled.0.pins=0x0002 +#hint.gpioled.0.at="gpiobus0" +#hint.gpioled.0.name="usb" +#hint.gpioled.0.pins=0x0002 hint.gpioled.1.at="gpiobus0" hint.gpioled.1.name="system" @@ -116,3 +116,17 @@ hint.gpioled.2.pins=0x0020 hint.gpioled.3.at="gpiobus0" hint.gpioled.3.name="wlan" hint.gpioled.3.pins=0x0200 + +# GPIO I2C bus +hint.gpioiic.0.at="gpiobus0" +hint.gpioiic.0.pins=0xc0000 +hint.gpioiic.0.scl=1 +hint.gpioiic.0.sda=0 + +# I2C bus +# Don't be strict about I2C protocol - the relaxed semantics are required +# by the realtek switch PHY. +hint.iicbus.0.strict=0 + +# Bit bang bus - override default delay +#hint.iicbb.0.udelay=3 diff --git a/sys/mips/conf/WRT160NL b/sys/mips/conf/WRT160NL new file mode 100644 index 0000000..083f128 --- /dev/null +++ b/sys/mips/conf/WRT160NL @@ -0,0 +1,49 @@ +# +# WRT160NL -- Kernel configuration file for the Cisco WRT160NL +# +# $FreeBSD$ +# + +# Include the default AR913x parameters common to all AR913x SoC users. +include "AR91XX_BASE" + +ident WRT160NL + +# Override hints with board values +hints "WRT160NL.hints" + +# Force the board memory - 32mb +options AR71XX_REALMEM=32*1024*1024 + +# read MSDOS formatted disks - USB +options MSDOSFS +options GEOM_PART_BSD +options GEOM_PART_MBR + +# Enable the uboot environment stuff rather then the +# redboot stuff. +options AR71XX_ENV_UBOOT + +# uzip - to boot natively from flash +device geom_uzip +options GEOM_UZIP + +# Used for the static uboot partition map +device geom_map + +# Boot off of the rootfs, as defined in the geom_map setup. +#options ROOTDEVNAME=\"ufs:map/rootfs.uzip\" +options ROOTDEVNAME=\"ufs:da0s1a\" + +# stb development stuff +options BREAK_TO_DEBUGGER +options ALT_BREAK_TO_DEBUGGER +#nooptions INVARIANTS +#nooptions INVARIANT_SUPPORT +#nooptions WITNESS +#nooptions WITNESS_SKIPSPIN +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options NFSCL +options NFS_ROOT diff --git a/sys/mips/conf/WRT160NL.hints b/sys/mips/conf/WRT160NL.hints new file mode 100644 index 0000000..38ecdf0 --- /dev/null +++ b/sys/mips/conf/WRT160NL.hints @@ -0,0 +1,132 @@ +# +# This file adds to the values in AR91XX_BASE.hints. +# +# $FreeBSD$ + +# Hard-code the PHY for now, until there's switch phy support. +hint.arge.0.phymask=0x0001 +hint.arge.0.media=1000 +hint.arge.0.fduplex=1 +# Where is the MAC address stored in flash for this particular unit. +hint.arge.0.eeprommac=0x1f01fc00 + +hint.arge.1.phymask=0x10 + +# Where the ART is +hint.ath.0.eepromaddr=0x1fff1000 + +# +# Define a slightly custom flash layout. + +# The default flash layout: +# +# 128k: uboot +# 1024k: kernel +# 4096k: rootfs +# 2816: unknown +# 64k: board config? +# 64k: ART +# +# from printenv: +# bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init +# mtdparts=ar9100-nor0:128k(u-boot),1024k(kernel),4096k(rootfs),64k(art) + +# This isn't a lot of space! +# So: +# 128k: uboot +# 2048k: kernel +# 5888k: rootfs +# 64k: config +# 64k: ART + +hint.map.0.at="flash/spi0" +hint.map.0.start=0x00000000 +hint.map.0.end=0x000040000 +hint.map.0.name="uboot" +hint.map.0.readonly=1 + +hint.map.1.at="flash/spi0" +hint.map.1.start=0x00040000 +hint.map.1.end=0x00220000 +hint.map.1.name="kernel" +hint.map.1.readonly=1 + +hint.map.2.at="flash/spi0" +hint.map.2.start=0x00220000 +hint.map.2.end=0x007e0000 +hint.map.2.name="rootfs" +hint.map.2.readonly=1 + +hint.map.3.at="flash/spi0" +hint.map.3.start=0x007e0000 +hint.map.3.end=0x007f0000 +hint.map.3.name="cfg" +hint.map.3.readonly=0 + +# This is radio calibration section. It is (or should be!) unique +# for each board, to take into account thermal and electrical differences +# as well as the regulatory compliance data. +# +hint.map.4.at="flash/spi0" +hint.map.4.start=0x007f0000 +hint.map.4.end=0x00800000 +hint.map.4.name="art" +hint.map.4.readonly=1 + +hint.map.5.at="flash/spi0" +hint.map.5.start=0x00000000 +hint.map.5.end=0x00800000 +hint.map.5.name="flash" +hint.map.5.readonly=1 + +# GPIO specific configuration block + +# Don't flip on anything that isn't already enabled. +# This includes leaving the SPI CS1/CS2 pins as GPIO pins as they're +# not used here. +hint.gpio.0.function_set=0x00000000 +hint.gpio.0.function_clear=0x00000000 + +# These are the GPIO LEDs and buttons which can be software controlled. +hint.gpio.0.pinmask=0x001c02ae + +# pin 1 - USB (LED) +# pin 2 - System (LED) +# Pin 3 - Reset (input) +# Pin 5 - QSS (LED) +# Pin 7 - QSS Button (input) +# Pin 8 - wired into the chip reset line +# Pin 9 - WLAN +# Pin 10 - UART TX (not GPIO) +# Pin 13 - UART RX (not GPIO) +# Pin 18 - RTL8366RB switch data line +# Pin 19 - RTL8366RB switch clock line +# Pin 20 - "GPIO20" + +# LEDs are configured separately and driven by the LED device +hint.gpioled.0.at="gpiobus0" +hint.gpioled.0.name="usb" +hint.gpioled.0.pins=0x0002 + +hint.gpioled.1.at="gpiobus0" +hint.gpioled.1.name="system" +hint.gpioled.1.pins=0x0004 + +hint.gpioled.2.at="gpiobus0" +hint.gpioled.2.name="qss" +hint.gpioled.2.pins=0x0020 + +hint.gpioled.3.at="gpiobus0" +hint.gpioled.3.name="wlan" +hint.gpioled.3.pins=0x0200 + +# GPIO I2C bus +hint.gpioiic.0.at="gpiobus0" +hint.gpioiic.0.pins=0xc0000 +hint.gpioiic.0.scl=1 +hint.gpioiic.0.sda=0 + +# I2C bus +# Don't be strict about I2C protocol - the relaxed semantics are required +# by the realtek switch PHY. +hint.iicbus.0.strict=0 diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 3a3f5e2..2f53854 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -92,6 +92,7 @@ SUBDIR= ${_3dfx} \ ${_epic} \ esp \ ${_et} \ + etherswitch \ ${_ex} \ ${_exca} \ ${_ext2fs} \ @@ -265,6 +266,7 @@ SUBDIR= ${_3dfx} \ re \ reiserfs \ rl \ + rtl8366rb \ runfw \ ${_s3} \ ${_safe} \ diff --git a/sys/modules/ath/Makefile b/sys/modules/ath/Makefile index 6e2e7b7..acf61b1 100644 --- a/sys/modules/ath/Makefile +++ b/sys/modules/ath/Makefile @@ -105,7 +105,7 @@ SRCS+= ar9160_attach.c # (currently) breaks non-AR9130 chipsets - since this is an embedded # chipset and no other radios are glued to it, this shouldn't pose a # problem. -SRCS+= ar9130_attach.c ar9130_eeprom.c ar9130_phy.c +# SRCS+= ar9130_attach.c ar9130_eeprom.c ar9130_phy.c # AR9002 series chips # + AR9220/AR9280 - Merlin @@ -140,8 +140,10 @@ SRCS+= dfs_null.c CFLAGS+= -I. -I${.CURDIR}/../../dev/ath -I${.CURDIR}/../../dev/ath/ath_hal +.if !defined(KERNBUILDDIR) opt_ah.h: echo '#define AH_SUPPORT_AR5416 1' > $@ +.endif .include diff --git a/sys/modules/etherswitch/Makefile b/sys/modules/etherswitch/Makefile new file mode 100644 index 0000000..b40a41e --- /dev/null +++ b/sys/modules/etherswitch/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/etherswitch +KMOD= etherswitch +SRCS= etherswitch.c device_if.h bus_if.h etherswitch_if.h +SRCS+= opt_cputype.h etherswitch_if.c + +.include diff --git a/sys/modules/rtl8366rb/Makefile b/sys/modules/rtl8366rb/Makefile new file mode 100644 index 0000000..40983ea --- /dev/null +++ b/sys/modules/rtl8366rb/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/etherswitch +KMOD= rtl8366rb +SRCS= rtl8366rb.c rtl8366rbvar.h +SRCS+= device_if.h bus_if.h iicbus_if.h miibus_if.h etherswitch_if.h opt_cputype.h opt_global.h + +.include --Apple-Mail=_CE96FAC5-9AF0-44EF-BFDB-F3380CF6C0C4-- From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 23:35:19 2012 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 09EEA106564A; Fri, 20 Jan 2012 23:35:19 +0000 (UTC) (envelope-from stb@lassitu.de) Received: from gilb.zs64.net (gilb.zs64.net [IPv6:2001:470:1f0b:105e::1ea]) by mx1.freebsd.org (Postfix) with ESMTP id C069C8FC0A; Fri, 20 Jan 2012 23:35:18 +0000 (UTC) Received: by gilb.zs64.net (Postfix, from stb@lassitu.de) id C780211D5BB; Fri, 20 Jan 2012 23:35:17 +0000 (UTC) Mime-Version: 1.0 (Apple Message framework v1251.1) Content-Type: text/plain; charset=us-ascii From: Stefan Bethke In-Reply-To: <20120120221319.ca8b631f.ray@freebsd.org> Date: Sat, 21 Jan 2012 00:35:16 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <20120120221319.ca8b631f.ray@freebsd.org> To: Aleksandr Rybalko X-Mailer: Apple Mail (2.1251.1) Cc: freebsd-net@FreeBSD.org, freebsd-arch@FreeBSD.org Subject: Re: Ethernet Switch Framework X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 23:35:19 -0000 Thank you for the update, that clears up a number of questions I had. Here's a couple of questions and comments. Which devices can this code be run on? For example, can the AR7240 = config run on an TL-WR3420? Would you mind giving an overview of how the various parts fit together, = how they are probed and attached? I think I understand from you = explanations on IRC, but not everbody had that chance. Am 20.01.2012 um 21:13 schrieb Aleksandr Rybalko: > get/set reg: > Generic access to registers. Have 2 address modifiers: > 0x00000000(no modifiers) - access to parent space (parent MDIO bus, if > switchX attaches to miibusX) > 0x40000000 - access to switch MDIO bus > 0x80000000 - access to switch registers. Wouldn't it be better to have a proper API to select the various busses = and device register files? > FloatPHY > pseudo driver which attach to miibus like normal PHY, but do find > master switchX device and ask his PHY reg's. Main problem with that > driver - is usage of newbus calls between independent device (not a > parent <-> child), since floatphyX query set/get methods of switchX. The general approach has a number of problems, as far as I understand = the miibus code. miibus assumes that only one of the PHYs on the MII is = active concurrently (since that's a requirement of the MII/GMII/... = bus). If I read your code correctly, you have one miibus that has all = the PHYs for all switch ports on them. Won't miibus just isolate all = but one PHY? In your current implementation, you've reimplented ukphy (in a limited = fashion). One of the advantages of reusing the mii framework is being = able to use all the PHYs, in case a switch chip would include a quirky = PHY. Extending floatphy to work as a full proxy for any phy driver = looks non-trivial to me due to the API constraints the mii framework = imposes. Stefan --=20 Stefan Bethke Fon +49 151 14070811 From owner-freebsd-net@FreeBSD.ORG Fri Jan 20 23:58:11 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 56C96106567A for ; Fri, 20 Jan 2012 23:58:11 +0000 (UTC) (envelope-from stb@lassitu.de) Received: from gilb.zs64.net (gilb.zs64.net [IPv6:2001:470:1f0b:105e::1ea]) by mx1.freebsd.org (Postfix) with ESMTP id 6F20D8FC19 for ; Fri, 20 Jan 2012 23:58:10 +0000 (UTC) Received: by gilb.zs64.net (Postfix, from stb@lassitu.de) id 731EA11D87D; Fri, 20 Jan 2012 23:58:09 +0000 (UTC) Mime-Version: 1.0 (Apple Message framework v1251.1) Content-Type: text/plain; charset=us-ascii From: Stefan Bethke In-Reply-To: <20111214011657.GH36635@alchemy.franken.de> Date: Sat, 21 Jan 2012 00:58:08 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <600A8C6C-DAB4-4E22-A034-38224017166B@lassitu.de> <20111213025041.GF3705@michelle.cdnetworks.com> <45B0B859-207C-4F02-A28F-7E34B775A273@lassitu.de> <20111213185348.GA7546@michelle.cdnetworks.com> <20111214011657.GH36635@alchemy.franken.de> To: Marius Strobl X-Mailer: Apple Mail (2.1251.1) Cc: YongHyeon PYUN , FreeBSD Net Subject: Re: "ifconfig media off"? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 23:58:11 -0000 Am 14.12.2011 um 02:16 schrieb Marius Strobl: > On Tue, Dec 13, 2011 at 10:53:48AM -0800, YongHyeon PYUN wrote: >> On Tue, Dec 13, 2011 at 11:04:51AM +0100, Stefan Bethke wrote: >>> Am 13.12.2011 um 03:50 schrieb YongHyeon PYUN: >>>=20 >>>> On Tue, Dec 13, 2011 at 12:56:22AM +0100, Stefan Bethke wrote: >>>>> I'm currently writing a driver to configure an ethernet switch = chip (see TL-WR1043ND on -embedded). >>>>>=20 >>>>> I noticed that there doesn't seem to be a way to power down a phy = right now through the ifconfig media command. >>>>>=20 >>>>> Would there be objections to extend the media subtype definitions = to include an "off", "poweroff" or "down" media subtype, and add code to = the relevant phy drivers to power down the phy for this media subtype? >>>>>=20 >>>>> The difference between media subtype "none" and this new one would = be that there will be no link, even if there is a physical connection. = With media subtype "none", a 10 MBit/s half-duplex connection is = established, potentially confusing the remote end about the availability = of this link. On the local side, the link is down, so no packets are = exchanged. >>>>>=20 >>>>=20 >>>> I think "none" means "isolated" so should have no established link >>>> and probably you can also power down the PHY. >>>> I vaguely guess the PHY of switch chip does not correctly support >>>> isolated mode so you may have wanted to power down. >>>=20 >>>=20 >>> After looking at the code a bit more, I think the common code just = doesn't set the BMCR_PDOWN (but clears it when bringing up the PHY). >>>=20 >>=20 >> Yes, and most PHYs could be powered down when BMCR_ISO is chosen. >> I'm not sure whether this could be applied to hardwares that >> support multiple PHYs(i.e. internal and external transceivers) >> though. Marius may have some opinions on this(CCed). >> However powering down PHY with BMCR_ISO looks natural to me. >>=20 >>> Index: sys/dev/mii/mii_physubr.c >>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>> --- sys/dev/mii/mii_physubr.c (revision 228402) >>> +++ sys/dev/mii/mii_physubr.c (working copy) >>> @@ -58,7 +58,7 @@ >>> */ >>> static const struct mii_media mii_media_table[MII_NMEDIA] =3D { >>> /* None */ >>> - { BMCR_ISO, ANAR_CSMA, >>> + { BMCR_ISO | BMCR_PDOWN, ANAR_CSMA, >>> 0, }, >>>=20 >>> /* 10baseT */ >>>=20 >>> I've opened kern/163240. >>> http://www.freebsd.org/cgi/query-pr.cgi?pr=3D163240 I'd like to revisit this. Just to reiterate my motivation for the = change: I want to be able to indicate to the remote end that my station = is not active. With the PHY just isolated from the MII, the link stays = up and functional (and even autoneg continues to work), so the remote = has no indication that it's just shouting into a void. > I don't think powering down the PHY along with IFM_NONE especially > in that way is a good idea for several reasons: > - It's incomplete as not all PHY drivers use mii_phy_add_media()/ > mii_phy_setmedia(). > - Even for those that do IFM_NONE isn't added when the PHY driver > sets MIIF_NOISOLATE (for some PHYs BMCR_ISO either just doesn't > work as especially the built-in ones probably have been designed > with only single-PHY configurations in mind or even wedges the > chip up to the point that even a reset doesn't get it working > again). In general though, BMCR_ISO and BMCR_PDOWN are orthogonal > (even in IEEE 802.3-2008 as far as I can see), i.e. while BMCR_ISO > might be broken, BMCR_PDOWN could work (actually I'd expect > BMCR_PDOWN to be less fragile than BMCR_ISO). I didn't expect my suggestion to be the be-all end-all, only a quick and = easy way to allow compliant PHYs to be powered down, and I'm not sure = why a "complete" solution is required. I'd assume that PHYs setting = MIIF_NOISOLATE have specific requirements, so it's OK to not have the = power-down option available there. (Plus I don't have hardware I could = test that case on). > - There should be a way to let a PHY driver do something different > than setting BMCR_PDOWN when it's told to power down as f.e. at > least some Broadcom PHYs support a "super isolation" mode. Cool, but how does my suggestion stop anyone from implementing that? > - As you already mentioned in general there can be multiple PHYs > on one MII bus and I'd expect "power down that interface" to > mean to power all of them down (granted, MACs with multiple > PHYs are rather uncommon in reality but they do exist, f.e. > Allied Telesis has several card models that use two PHYs per > MAC). Since there can be only one active PHY at a time, it could make sense to = also set PDOWN in mii_mediachg(). How about a new flag MIIF_PDOWN that = the phy driver can set to indicate that it would rather be shut off than = just isolated? Right now I only care about ukphy anyway. > In generall I agree that there should be a way to power down PHYs > though. While there might be some merit in additionally adding that > as a media option I think that the most intuitive way would be for > `ifconfig foo0 down` to also power down the PHYs on that interface. > In order implement that the basic way seems to be to make the > various foo_stop() methods of MAC drivers to call mii_down() (as > in NetBSD) and to make mii_phy_down() (or a replacement) actually > do something, with PHY drivers being allowed to opt-out with > something like a MIIF_NOPOWERDOWN. What I'm not sure about is how > to implement power down in the individual drivers while keeping > code duplication for the common case low, i.e. I'm not sure whether > the NetBSD way of having a MII_DOWN case in the service routines > is the way to go. I'm hesitant to tie IFF_UP to link state. Is there precedent for that? = My gut feeling is that IFF_UP has always meant that the interface has = been brought up administratively; bringing an interface down "only" = means that the system should not transmit on it and discard received = frames. > Is there something in the rc.d scripts that downs network > interfaces on shutdown that could interfere with WOL when we > power down the PHYs? I don't think so, but I've never looked in detail. I believe that = interfaces are brought down on shutdown by the kernel, though. Stefan --=20 Stefan Bethke Fon +49 151 14070811 From owner-freebsd-net@FreeBSD.ORG Sat Jan 21 05:55:08 2012 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B20C4106564A; Sat, 21 Jan 2012 05:55:08 +0000 (UTC) (envelope-from csjp@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 7FA378FC15; Sat, 21 Jan 2012 05:55:08 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q0L5t86E000163; Sat, 21 Jan 2012 05:55:08 GMT (envelope-from csjp@freefall.freebsd.org) Received: (from csjp@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q0L5t870000159; Sat, 21 Jan 2012 05:55:08 GMT (envelope-from csjp) Date: Sat, 21 Jan 2012 05:55:08 GMT Message-Id: <201201210555.q0L5t870000159@freefall.freebsd.org> To: csjp@FreeBSD.org, freebsd-net@FreeBSD.org, csjp@FreeBSD.org From: csjp@FreeBSD.org Cc: Subject: Re: kern/163370: [bpf] [request] enable zero-copy BPF by default X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Jan 2012 05:55:08 -0000 Synopsis: [bpf] [request] enable zero-copy BPF by default Responsible-Changed-From-To: freebsd-net->csjp Responsible-Changed-By: csjp Responsible-Changed-When: Sat Jan 21 05:54:39 UTC 2012 Responsible-Changed-Why: Take, I will follow up with Guy http://www.freebsd.org/cgi/query-pr.cgi?pr=163370 From owner-freebsd-net@FreeBSD.ORG Sat Jan 21 13:37:55 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 02A4A106564A for ; Sat, 21 Jan 2012 13:37:55 +0000 (UTC) (envelope-from nvass@gmx.com) Received: from mailout-us.gmx.com (mailout-us.gmx.com [74.208.5.67]) by mx1.freebsd.org (Postfix) with SMTP id B4BFA8FC14 for ; Sat, 21 Jan 2012 13:37:54 +0000 (UTC) Received: (qmail invoked by alias); 21 Jan 2012 13:37:52 -0000 Received: from unknown (EHLO [192.168.73.192]) [91.140.99.89] by mail.gmx.com (mp-us006) with SMTP; 21 Jan 2012 08:37:52 -0500 X-Authenticated: #46156728 X-Provags-ID: V01U2FsdGVkX1+iErpuT++i0nX2bIOZweeyTtysbl70BuLH2D64Hk nJJB6EYuSzQ1Pi Message-ID: <4F1ABF9C.5010608@gmx.com> Date: Sat, 21 Jan 2012 15:37:32 +0200 From: Nikos Vassiliadis User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: multipart/mixed; boundary="------------080102030109050709030808" X-Y-GMX-Trusted: 0 Subject: STP id selection X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Jan 2012 13:37:55 -0000 This is a multi-part message in MIME format. --------------080102030109050709030808 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, The current code in bridgestp.c finds the lower MAC address from all available ethernets and uses it as the STP id. This is problematic when more than one STP bridges participate in the same STP domain because more than one bridges will use the same id. A similar fix was applied to the OpenBSD version of the code[1]. Could you review the attached patch? 1.http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/bridgestp.c?rev=1.33 Thanks, Nikos --------------080102030109050709030808 Content-Type: text/plain; name="bridgestp.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="bridgestp.c.diff" Index: sys/net/bridgestp.c =================================================================== --- sys/net/bridgestp.c (revision 230309) +++ sys/net/bridgestp.c (working copy) @@ -2017,20 +2017,27 @@ BSTP_LOCK_ASSERT(bs); mif = NULL; + bp = LIST_FIRST(&bs->bs_bplist); /* * Search through the Ethernet adapters and find the one with the - * lowest value. The adapter which we take the MAC address from does - * not need to be part of the bridge, it just needs to be a unique - * value. + * lowest value. Make sure the adapter which we take the MAC address + * from is part of this bridge, so we can have more than one independent + * bridges in the same STP domain. */ IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; + if (ifp->if_bridge == NULL || bp == NULL) + continue; + if (bstp_addr_cmp(IF_LLADDR(ifp), llzero) == 0) continue; + if (ifp->if_bridge != bp->bp_ifp->if_bridge) + continue; + if (mif == NULL) { mif = ifp; continue; --------------080102030109050709030808--