Any comments on this?
2013/1/16 Dinar Talypov <[email protected]>: > 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.c 14 Oct 2011 17:08:09 -0000 1.52 > +++ ar5212.c 16 Jan 2013 16:58:33 -0000 > @@ -30,6 +30,7 @@ > u_int16_t ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP); > void ar5k_ar5212_fill(struct ath_hal *); > HAL_BOOL ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int); > +HAL_BOOL ar5k_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 <[email protected]>
