if_ath.c (152448) | if_ath.c (154140) |
---|---|
1/*- 2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 152448 2005-11-15 05:49:02Z sam $"); | 38__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 154140 2006-01-09 17:13:20Z sam $"); |
39 40/* 41 * Driver for the Atheros Wireless LAN controller. 42 * 43 * This software is derived from work of Atsushi Onoe; his contribution 44 * is greatly appreciated. 45 */ 46 --- 2488 unchanged lines hidden (view full) --- 2535 if (sc->sc_rxlink != NULL) 2536 *sc->sc_rxlink = bf->bf_daddr; 2537 sc->sc_rxlink = &ds->ds_link; 2538 return 0; 2539} 2540 2541/* 2542 * Extend 15-bit time stamp from rx descriptor to | 39 40/* 41 * Driver for the Atheros Wireless LAN controller. 42 * 43 * This software is derived from work of Atsushi Onoe; his contribution 44 * is greatly appreciated. 45 */ 46 --- 2488 unchanged lines hidden (view full) --- 2535 if (sc->sc_rxlink != NULL) 2536 *sc->sc_rxlink = bf->bf_daddr; 2537 sc->sc_rxlink = &ds->ds_link; 2538 return 0; 2539} 2540 2541/* 2542 * Extend 15-bit time stamp from rx descriptor to |
2543 * a full 64-bit TSF using the current h/w TSF. | 2543 * a full 64-bit TSF using the specified TSF. |
2544 */ 2545static __inline u_int64_t | 2544 */ 2545static __inline u_int64_t |
2546ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp) | 2546ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf) |
2547{ | 2547{ |
2548 u_int64_t tsf; 2549 2550 tsf = ath_hal_gettsf64(ah); | |
2551 if ((tsf & 0x7fff) < rstamp) 2552 tsf -= 0x8000; 2553 return ((tsf &~ 0x7fff) | rstamp); 2554} 2555 2556/* 2557 * Intercept management frames to collect beacon rssi data 2558 * and to do ibss merges. --- 13 unchanged lines hidden (view full) --- 2572 switch (subtype) { 2573 case IEEE80211_FC0_SUBTYPE_BEACON: 2574 /* update rssi statistics for use by the hal */ 2575 ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi); 2576 /* fall thru... */ 2577 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2578 if (ic->ic_opmode == IEEE80211_M_IBSS && 2579 ic->ic_state == IEEE80211_S_RUN) { | 2548 if ((tsf & 0x7fff) < rstamp) 2549 tsf -= 0x8000; 2550 return ((tsf &~ 0x7fff) | rstamp); 2551} 2552 2553/* 2554 * Intercept management frames to collect beacon rssi data 2555 * and to do ibss merges. --- 13 unchanged lines hidden (view full) --- 2569 switch (subtype) { 2570 case IEEE80211_FC0_SUBTYPE_BEACON: 2571 /* update rssi statistics for use by the hal */ 2572 ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi); 2573 /* fall thru... */ 2574 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2575 if (ic->ic_opmode == IEEE80211_M_IBSS && 2576 ic->ic_state == IEEE80211_S_RUN) { |
2580 u_int64_t tsf = ath_extend_tsf(sc->sc_ah, rstamp); | 2577 u_int64_t tsf = ath_extend_tsf(rstamp, 2578 ath_hal_gettsf64(sc->sc_ah)); |
2581 /* 2582 * Handle ibss merge as needed; check the tsf on the 2583 * frame before attempting the merge. The 802.11 spec 2584 * says the station should change it's bssid to match 2585 * the oldest station with the same ssid, where oldest 2586 * is determined by the tsf. Note that hardware 2587 * reconfiguration happens through callback to 2588 * ath_newstate as the state machine will go from --- 22 unchanged lines hidden (view full) --- 2611 /* XXX block beacon interrupts */ 2612 ath_hal_setdefantenna(ah, antenna); 2613 if (sc->sc_defant != antenna) 2614 sc->sc_stats.ast_ant_defswitch++; 2615 sc->sc_defant = antenna; 2616 sc->sc_rxotherant = 0; 2617} 2618 | 2579 /* 2580 * Handle ibss merge as needed; check the tsf on the 2581 * frame before attempting the merge. The 802.11 spec 2582 * says the station should change it's bssid to match 2583 * the oldest station with the same ssid, where oldest 2584 * is determined by the tsf. Note that hardware 2585 * reconfiguration happens through callback to 2586 * ath_newstate as the state machine will go from --- 22 unchanged lines hidden (view full) --- 2609 /* XXX block beacon interrupts */ 2610 ath_hal_setdefantenna(ah, antenna); 2611 if (sc->sc_defant != antenna) 2612 sc->sc_stats.ast_ant_defswitch++; 2613 sc->sc_defant = antenna; 2614 sc->sc_rxotherant = 0; 2615} 2616 |
2617static int 2618ath_rx_tap(struct ath_softc *sc, struct mbuf *m, 2619 const struct ath_desc *ds, u_int64_t tsf, int16_t nf) 2620{ 2621 u_int8_t rix; 2622 2623 KASSERT(sc->sc_drvbpf != NULL, ("no tap")); 2624 2625 /* 2626 * Discard anything shorter than an ack or cts. 2627 */ 2628 if (m->m_pkthdr.len < IEEE80211_ACK_LEN) { 2629 DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n", 2630 __func__, m->m_pkthdr.len); 2631 sc->sc_stats.ast_rx_tooshort++; 2632 return 0; 2633 } 2634 sc->sc_rx_th.wr_tsf = htole64( 2635 ath_extend_tsf(ds->ds_rxstat.rs_tstamp, tsf)); 2636 rix = ds->ds_rxstat.rs_rate; 2637 sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags; 2638 if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC) 2639 sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 2640 /* XXX propagate other error flags from descriptor */ 2641 sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate; 2642 sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi + nf; 2643 sc->sc_rx_th.wr_antnoise = nf; 2644 sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna; 2645 2646 bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); 2647 2648 return 1; 2649} 2650 |
|
2619static void 2620ath_rx_proc(void *arg, int npending) 2621{ 2622#define PA2DESC(_sc, _pa) \ 2623 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ 2624 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) 2625 struct ath_softc *sc = arg; 2626 struct ath_buf *bf; 2627 struct ieee80211com *ic = &sc->sc_ic; 2628 struct ifnet *ifp = sc->sc_ifp; 2629 struct ath_hal *ah = sc->sc_ah; 2630 struct ath_desc *ds; 2631 struct mbuf *m; 2632 struct ieee80211_node *ni; 2633 struct ath_node *an; 2634 int len, type; 2635 u_int phyerr; 2636 HAL_STATUS status; | 2651static void 2652ath_rx_proc(void *arg, int npending) 2653{ 2654#define PA2DESC(_sc, _pa) \ 2655 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ 2656 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) 2657 struct ath_softc *sc = arg; 2658 struct ath_buf *bf; 2659 struct ieee80211com *ic = &sc->sc_ic; 2660 struct ifnet *ifp = sc->sc_ifp; 2661 struct ath_hal *ah = sc->sc_ah; 2662 struct ath_desc *ds; 2663 struct mbuf *m; 2664 struct ieee80211_node *ni; 2665 struct ath_node *an; 2666 int len, type; 2667 u_int phyerr; 2668 HAL_STATUS status; |
2669 int16_t nf; 2670 u_int64_t tsf; |
|
2637 2638 NET_LOCK_GIANT(); /* XXX */ 2639 2640 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); | 2671 2672 NET_LOCK_GIANT(); /* XXX */ 2673 2674 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); |
2675 nf = ath_hal_getchannoise(ah, &sc->sc_curchan); 2676 tsf = ath_hal_gettsf64(ah); |
|
2641 do { 2642 bf = STAILQ_FIRST(&sc->sc_rxbuf); 2643 if (bf == NULL) { /* NB: shouldn't happen */ 2644 if_printf(ifp, "%s: no buffer!\n", __func__); 2645 break; 2646 } 2647 ds = bf->bf_desc; 2648 if (ds->ds_link == bf->bf_daddr) { --- 81 unchanged lines hidden (view full) --- 2730 sc->sc_splitmic ? 2731 ds->ds_rxstat.rs_keyix-32 : 2732 ds->ds_rxstat.rs_keyix 2733 ); 2734 } 2735 } 2736 ifp->if_ierrors++; 2737 /* | 2677 do { 2678 bf = STAILQ_FIRST(&sc->sc_rxbuf); 2679 if (bf == NULL) { /* NB: shouldn't happen */ 2680 if_printf(ifp, "%s: no buffer!\n", __func__); 2681 break; 2682 } 2683 ds = bf->bf_desc; 2684 if (ds->ds_link == bf->bf_daddr) { --- 81 unchanged lines hidden (view full) --- 2766 sc->sc_splitmic ? 2767 ds->ds_rxstat.rs_keyix-32 : 2768 ds->ds_rxstat.rs_keyix 2769 ); 2770 } 2771 } 2772 ifp->if_ierrors++; 2773 /* |
2738 * Reject error frames, we normally don't want 2739 * to see them in monitor mode (in monitor mode 2740 * allow through packets that have crypto problems). | 2774 * When a tap is present pass error frames 2775 * that have been requested. By default we 2776 * pass decrypt+mic errors but others may be 2777 * interesting (e.g. crc). |
2741 */ | 2778 */ |
2742 if ((ds->ds_rxstat.rs_status &~ 2743 (HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) || 2744 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 2745 goto rx_next; | 2779 if (sc->sc_drvbpf != NULL && 2780 (ds->ds_rxstat.rs_status & sc->sc_monpass)) { 2781 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 2782 BUS_DMASYNC_POSTREAD); 2783 /* NB: bpf needs the mbuf length setup */ 2784 len = ds->ds_rxstat.rs_datalen; 2785 m->m_pkthdr.len = m->m_len = len; 2786 (void) ath_rx_tap(sc, m, ds, tsf, nf); 2787 } 2788 /* XXX pass MIC errors up for s/w reclaculation */ 2789 goto rx_next; |
2746 } 2747rx_accept: 2748 /* 2749 * Sync and unmap the frame. At this point we're 2750 * committed to passing the mbuf somewhere so clear 2751 * bf_m; this means a new sk_buff must be allocated 2752 * when the rx descriptor is setup again to receive 2753 * another frame. --- 4 unchanged lines hidden (view full) --- 2758 bf->bf_m = NULL; 2759 2760 m->m_pkthdr.rcvif = ifp; 2761 len = ds->ds_rxstat.rs_datalen; 2762 m->m_pkthdr.len = m->m_len = len; 2763 2764 sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++; 2765 | 2790 } 2791rx_accept: 2792 /* 2793 * Sync and unmap the frame. At this point we're 2794 * committed to passing the mbuf somewhere so clear 2795 * bf_m; this means a new sk_buff must be allocated 2796 * when the rx descriptor is setup again to receive 2797 * another frame. --- 4 unchanged lines hidden (view full) --- 2802 bf->bf_m = NULL; 2803 2804 m->m_pkthdr.rcvif = ifp; 2805 len = ds->ds_rxstat.rs_datalen; 2806 m->m_pkthdr.len = m->m_len = len; 2807 2808 sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++; 2809 |
2766 if (sc->sc_drvbpf) { 2767 u_int8_t rix; 2768 2769 /* 2770 * Discard anything shorter than an ack or cts. 2771 */ 2772 if (len < IEEE80211_ACK_LEN) { 2773 DPRINTF(sc, ATH_DEBUG_RECV, 2774 "%s: runt packet %d\n", 2775 __func__, len); 2776 sc->sc_stats.ast_rx_tooshort++; 2777 m_freem(m); 2778 goto rx_next; 2779 } 2780 rix = ds->ds_rxstat.rs_rate; 2781 sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags; 2782 sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate; 2783 sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi; 2784 sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna; 2785 /* XXX TSF */ 2786 2787 bpf_mtap2(sc->sc_drvbpf, 2788 &sc->sc_rx_th, sc->sc_rx_th_len, m); | 2810 if (sc->sc_drvbpf != NULL && !ath_rx_tap(sc, m, ds, tsf, nf)) { 2811 m_freem(m); /* XXX reclaim */ 2812 goto rx_next; |
2789 } 2790 2791 /* 2792 * From this point on we assume the frame is at least 2793 * as large as ieee80211_frame_min; verify that. 2794 */ 2795 if (len < IEEE80211_MIN_LEN) { 2796 DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n", --- 640 unchanged lines hidden (view full) --- 3437 3438 if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT)) 3439 ieee80211_dump_pkt(mtod(m0, caddr_t), m0->m_len, 3440 sc->sc_hwmap[txrate].ieeerate, -1); 3441 3442 if (ic->ic_rawbpf) 3443 bpf_mtap(ic->ic_rawbpf, m0); 3444 if (sc->sc_drvbpf) { | 2813 } 2814 2815 /* 2816 * From this point on we assume the frame is at least 2817 * as large as ieee80211_frame_min; verify that. 2818 */ 2819 if (len < IEEE80211_MIN_LEN) { 2820 DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n", --- 640 unchanged lines hidden (view full) --- 3461 3462 if (IFF_DUMPPKTS(sc, ATH_DEBUG_XMIT)) 3463 ieee80211_dump_pkt(mtod(m0, caddr_t), m0->m_len, 3464 sc->sc_hwmap[txrate].ieeerate, -1); 3465 3466 if (ic->ic_rawbpf) 3467 bpf_mtap(ic->ic_rawbpf, m0); 3468 if (sc->sc_drvbpf) { |
3469 u_int64_t tsf = ath_hal_gettsf64(ah); 3470 3471 sc->sc_tx_th.wt_tsf = htole64(tsf); |
|
3445 sc->sc_tx_th.wt_flags = sc->sc_hwmap[txrate].txflags; 3446 if (iswep) 3447 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 3448 sc->sc_tx_th.wt_rate = sc->sc_hwmap[txrate].ieeerate; 3449 sc->sc_tx_th.wt_txpower = ni->ni_txpower; 3450 sc->sc_tx_th.wt_antenna = sc->sc_txantenna; 3451 3452 bpf_mtap2(sc->sc_drvbpf, --- 566 unchanged lines hidden (view full) --- 4019 ath_reset(sc->sc_ifp); 4020 } 4021 if (!ath_hal_calibrate(ah, &sc->sc_curchan)) { 4022 DPRINTF(sc, ATH_DEBUG_ANY, 4023 "%s: calibration of channel %u failed\n", 4024 __func__, sc->sc_curchan.channel); 4025 sc->sc_stats.ast_per_calfail++; 4026 } | 3472 sc->sc_tx_th.wt_flags = sc->sc_hwmap[txrate].txflags; 3473 if (iswep) 3474 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 3475 sc->sc_tx_th.wt_rate = sc->sc_hwmap[txrate].ieeerate; 3476 sc->sc_tx_th.wt_txpower = ni->ni_txpower; 3477 sc->sc_tx_th.wt_antenna = sc->sc_txantenna; 3478 3479 bpf_mtap2(sc->sc_drvbpf, --- 566 unchanged lines hidden (view full) --- 4046 ath_reset(sc->sc_ifp); 4047 } 4048 if (!ath_hal_calibrate(ah, &sc->sc_curchan)) { 4049 DPRINTF(sc, ATH_DEBUG_ANY, 4050 "%s: calibration of channel %u failed\n", 4051 __func__, sc->sc_curchan.channel); 4052 sc->sc_stats.ast_per_calfail++; 4053 } |
4054 /* 4055 * Calibrate noise floor data again in case of change. 4056 */ 4057 ath_hal_process_noisefloor(ah); |
|
4027 callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc); 4028} 4029 4030static int 4031ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 4032{ 4033 struct ifnet *ifp = ic->ic_ifp; 4034 struct ath_softc *sc = ifp->if_softc; --- 99 unchanged lines hidden (view full) --- 4134 ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE) 4135 ath_setup_stationkey(ni); 4136 break; 4137 default: 4138 break; 4139 } 4140 4141 /* | 4058 callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc); 4059} 4060 4061static int 4062ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 4063{ 4064 struct ifnet *ifp = ic->ic_ifp; 4065 struct ath_softc *sc = ifp->if_softc; --- 99 unchanged lines hidden (view full) --- 4165 ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE) 4166 ath_setup_stationkey(ni); 4167 break; 4168 default: 4169 break; 4170 } 4171 4172 /* |
4173 * Let the hal process statistics collected during a 4174 * scan so it can provide calibrated noise floor data. 4175 */ 4176 ath_hal_process_noisefloor(ah); 4177 /* |
|
4142 * Configure the beacon and sleep timers. 4143 */ 4144 ath_beacon_config(sc); 4145 } else { 4146 ath_hal_intrset(ah, 4147 sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); 4148 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); 4149 } --- 706 unchanged lines hidden (view full) --- 4856 ath_sysctl_diag, "I", "h/w diagnostic control"); 4857 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4858 "tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0, 4859 ath_sysctl_tpscale, "I", "tx power scaling"); 4860 if (ath_hal_hastpc(ah)) 4861 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4862 "tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0, 4863 ath_sysctl_tpc, "I", "enable/disable per-packet TPC"); | 4178 * Configure the beacon and sleep timers. 4179 */ 4180 ath_beacon_config(sc); 4181 } else { 4182 ath_hal_intrset(ah, 4183 sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); 4184 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); 4185 } --- 706 unchanged lines hidden (view full) --- 4892 ath_sysctl_diag, "I", "h/w diagnostic control"); 4893 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4894 "tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0, 4895 ath_sysctl_tpscale, "I", "tx power scaling"); 4896 if (ath_hal_hastpc(ah)) 4897 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4898 "tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0, 4899 ath_sysctl_tpc, "I", "enable/disable per-packet TPC"); |
4900 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC; 4901 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4902 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0, 4903 "mask of error frames to pass when monitoring"); |
|
4864} 4865 4866static void 4867ath_bpfattach(struct ath_softc *sc) 4868{ 4869 struct ifnet *ifp = sc->sc_ifp; 4870 4871 bpfattach2(ifp, DLT_IEEE802_11_RADIO, --- 68 unchanged lines hidden --- | 4904} 4905 4906static void 4907ath_bpfattach(struct ath_softc *sc) 4908{ 4909 struct ifnet *ifp = sc->sc_ifp; 4910 4911 bpfattach2(ifp, DLT_IEEE802_11_RADIO, --- 68 unchanged lines hidden --- |