system freeze with DWL-G520 and possible fix

2013-01-16 Thread Dinar Talypov
Hi,

My D-link DWL-G520 card attaches on ath(4):

ath0 at pci0 dev 9 function 0 Atheros AR5212 rev 0x01: irq 11
ath0: AR2414 7.9 phy 4.5 rf2413 5.6, FCC2A*, address 00:17:9a:09:f4:5a

On ifconfig ath0 down  ifconfig ath0 up I've got system freeze.

Googleing showed that system can freeze on register read or write
while AR5212 chip in full sleep mode. And it is not possible to wake it up.
This implies only for some AR5212 chips.

In linux this is solved by making warm reset, instead 
of putting it in full sleep mode.
The diff below does the same thing.
What do you think about it? Or warm_reset function 
must be called only for particular chips?

Index: ar5212.c
===
RCS file: /cvs/src/sys/dev/ic/ar5212.c,v
retrieving revision 1.52
diff -u -r1.52 ar5212.c
--- ar5212.c14 Oct 2011 17:08:09 -  1.52
+++ ar5212.c16 Jan 2013 16:58:33 -
@@ -30,6 +30,7 @@
 u_int16_t   ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
 voidar5k_ar5212_fill(struct ath_hal *);
 HAL_BOOLar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
+HAL_BOOLar5k_ar5212_warm_reset(struct ath_hal *);
 
 /*
  * Initial register setting for the AR5212
@@ -2420,6 +2421,44 @@
 }
 
 /*
+ * Put MAC and Baseband on warm reset and keep that state
+ * (don't clean sleep control register). After this MAC
+ * and Baseband are disabled and a full reset is needed
+ * to come back. This way we save as much power as possible
+ * without putting the card on full sleep.
+ */
+
+HAL_BOOL
+ar5k_ar5212_warm_reset(struct ath_hal *hal)
+{
+   u_int32_t flags;
+
+   flags = AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
+   if (hal-ah_pci_express == AH_FALSE)
+   flags |= AR5K_AR5212_RC_PCI;
+
+   if (ar5k_ar5212_nic_reset(hal, flags) == AH_FALSE) {
+   AR5K_PRINT(failed to reset the AR5212 + PCI chipset\n);
+   return (AH_FALSE);
+   }
+
+   /* ...wakeup */
+   if (ar5k_ar5212_set_power(hal,
+   HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
+   AR5K_PRINT(failed to resume the AR5212 (again)\n);
+   return (AH_FALSE);
+   }
+
+   /* Put chipset on warm reset... */
+   if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
+   AR5K_PRINT(failed to warm reset the AR5212\n);
+   return (AH_FALSE);
+   }
+
+   return (AH_TRUE);
+}
+
+/*
  * Power management functions
  */
 
@@ -2445,10 +2484,8 @@
break;
 
case HAL_PM_FULL_SLEEP:
-   if (set_chip == AH_TRUE) {
-   AR5K_REG_WRITE(AR5K_AR5212_SCR,
-   AR5K_AR5212_SCR_SLE_SLP);
-   }
+   if (set_chip == AH_TRUE)
+   ar5k_ar5212_warm_reset(hal);
staid |= AR5K_AR5212_STA_ID1_PWR_SV;
break;
 


-- 
Dinar Talypov t.dina...@gmail.com



allow sending certain frames on trunkdevs for LLDP

2013-01-16 Thread Stuart Henderson
Daemons which send LLDP advertisements (e.g. ladvd and lldpd) need to
send frames on trunk member ports in order that the individual port can
be identified to the switch; currently there is a blanket restriction
on sending via these ports, the following diff changes this to permit
AF_UNSPEC and pseudo_AF_HDRCMPLT as suggested by Sten Spans (ladvd
author).

Comments? OK?


Index: if_ethersubr.c
===
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.152
diff -u -p -r1.152 if_ethersubr.c
--- if_ethersubr.c  5 Oct 2012 17:17:04 -   1.152
+++ if_ethersubr.c  16 Jan 2013 22:51:19 -
@@ -227,7 +227,8 @@ ether_output(ifp0, m0, dst, rt0)
 #endif
 
 #if NTRUNK  0
-   if (ifp-if_type == IFT_IEEE8023ADLAG)
+   if (ifp-if_type == IFT_IEEE8023ADLAG  dst-sa_family != AF_UNSPEC
+dst-sa_family != pseudo_AF_HDRCMPLT)
senderr(EBUSY);
 #endif



Re: allow sending certain frames on trunkdevs for LLDP

2013-01-16 Thread Marco Pfatschbacher
On Wed, Jan 16, 2013 at 10:56:25PM +, Stuart Henderson wrote:
 Daemons which send LLDP advertisements (e.g. ladvd and lldpd) need to
 send frames on trunk member ports in order that the individual port can
 be identified to the switch; currently there is a blanket restriction
 on sending via these ports, the following diff changes this to permit
 AF_UNSPEC and pseudo_AF_HDRCMPLT as suggested by Sten Spans (ladvd
 author).
 
 Comments? OK?

Hmm, that feels a bit too unrestrictive.
I remember a cisco that was utterly confused when it received
STP on its trunkports. 
I wonder if there's sth in the standard about extra traffic
on the trunkports.

OTOH, if reyk@ only added the check as an extra safety net,
I'm fine with this.

reyk?


 Index: if_ethersubr.c
 ===
 RCS file: /cvs/src/sys/net/if_ethersubr.c,v
 retrieving revision 1.152
 diff -u -p -r1.152 if_ethersubr.c
 --- if_ethersubr.c5 Oct 2012 17:17:04 -   1.152
 +++ if_ethersubr.c16 Jan 2013 22:51:19 -
 @@ -227,7 +227,8 @@ ether_output(ifp0, m0, dst, rt0)
  #endif
  
  #if NTRUNK  0
 - if (ifp-if_type == IFT_IEEE8023ADLAG)
 + if (ifp-if_type == IFT_IEEE8023ADLAG  dst-sa_family != AF_UNSPEC
 +  dst-sa_family != pseudo_AF_HDRCMPLT)
   senderr(EBUSY);
  #endif



Re: allow sending certain frames on trunkdevs for LLDP

2013-01-16 Thread Claudio Jeker
On Thu, Jan 17, 2013 at 12:40:32AM +0100, Marco Pfatschbacher wrote:
 On Wed, Jan 16, 2013 at 10:56:25PM +, Stuart Henderson wrote:
  Daemons which send LLDP advertisements (e.g. ladvd and lldpd) need to
  send frames on trunk member ports in order that the individual port can
  be identified to the switch; currently there is a blanket restriction
  on sending via these ports, the following diff changes this to permit
  AF_UNSPEC and pseudo_AF_HDRCMPLT as suggested by Sten Spans (ladvd
  author).
  
  Comments? OK?
 
 Hmm, that feels a bit too unrestrictive.
 I remember a cisco that was utterly confused when it received
 STP on its trunkports. 
 I wonder if there's sth in the standard about extra traffic
 on the trunkports.
 
 OTOH, if reyk@ only added the check as an extra safety net,
 I'm fine with this.
 

We could also check for the PACKET_TAG_DLT on the mbuf so we limit sending
on the trunk ports to bpf only. IMO bpf is one of those tools that give
you enough rope to do cool shit but also to hang yourself so that should
be OK.

 reyk?
 
 
  Index: if_ethersubr.c
  ===
  RCS file: /cvs/src/sys/net/if_ethersubr.c,v
  retrieving revision 1.152
  diff -u -p -r1.152 if_ethersubr.c
  --- if_ethersubr.c  5 Oct 2012 17:17:04 -   1.152
  +++ if_ethersubr.c  16 Jan 2013 22:51:19 -
  @@ -227,7 +227,8 @@ ether_output(ifp0, m0, dst, rt0)
   #endif
   
   #if NTRUNK  0
  -   if (ifp-if_type == IFT_IEEE8023ADLAG)
  +   if (ifp-if_type == IFT_IEEE8023ADLAG  dst-sa_family != AF_UNSPEC
  +dst-sa_family != pseudo_AF_HDRCMPLT)
  senderr(EBUSY);
   #endif
 

-- 
:wq Claudio



Re: allow sending certain frames on trunkdevs for LLDP

2013-01-16 Thread Stuart Henderson
On 2013/01/17 00:56, Claudio Jeker wrote:
 On Thu, Jan 17, 2013 at 12:40:32AM +0100, Marco Pfatschbacher wrote:
  On Wed, Jan 16, 2013 at 10:56:25PM +, Stuart Henderson wrote:
   Daemons which send LLDP advertisements (e.g. ladvd and lldpd) need to
   send frames on trunk member ports in order that the individual port can
   be identified to the switch; currently there is a blanket restriction
   on sending via these ports, the following diff changes this to permit
   AF_UNSPEC and pseudo_AF_HDRCMPLT as suggested by Sten Spans (ladvd
   author).
   
   Comments? OK?
  
  Hmm, that feels a bit too unrestrictive.
  I remember a cisco that was utterly confused when it received
  STP on its trunkports. 
  I wonder if there's sth in the standard about extra traffic
  on the trunkports.
  
  OTOH, if reyk@ only added the check as an extra safety net,
  I'm fine with this.
  
 
 We could also check for the PACKET_TAG_DLT on the mbuf so we limit sending
 on the trunk ports to bpf only. IMO bpf is one of those tools that give
 you enough rope to do cool shit but also to hang yourself so that should
 be OK.

Ah yes, that probably makes more sense:

Index: if_ethersubr.c
===
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.152
diff -u -p -r1.152 if_ethersubr.c
--- if_ethersubr.c  5 Oct 2012 17:17:04 -   1.152
+++ if_ethersubr.c  17 Jan 2013 00:16:11 -
@@ -227,7 +227,9 @@ ether_output(ifp0, m0, dst, rt0)
 #endif
 
 #if NTRUNK  0
-   if (ifp-if_type == IFT_IEEE8023ADLAG)
+   /* restrict transmission on trunk members to bpf only */
+   if (ifp-if_type == IFT_IEEE8023ADLAG 
+   (m_tag_find(m, PACKET_TAG_DLT, NULL) == NULL))
senderr(EBUSY);
 #endif



Re: amd64 bus_space tweak

2013-01-16 Thread Janne Johansson
2013/1/16 David Gwynne da...@gwynne.id.au:
 i also make it possible for the compiler to inline bus_space_barrier,
 which can generally get reduced to a single instruction rather than
 a function call. as a result it makes the kernel smaller.


and THERE we got vi in. 8^D


-- 
May the most significant bit of your life be positive.