@@ -2481,6 +2481,25 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
24812481 }
24822482}
24832483
2484+ static u8 mt7615_mcu_chan_bw (struct cfg80211_chan_def * chandef )
2485+ {
2486+ static const u8 width_to_bw [] = {
2487+ [NL80211_CHAN_WIDTH_40 ] = CMD_CBW_40MHZ ,
2488+ [NL80211_CHAN_WIDTH_80 ] = CMD_CBW_80MHZ ,
2489+ [NL80211_CHAN_WIDTH_80P80 ] = CMD_CBW_8080MHZ ,
2490+ [NL80211_CHAN_WIDTH_160 ] = CMD_CBW_160MHZ ,
2491+ [NL80211_CHAN_WIDTH_5 ] = CMD_CBW_5MHZ ,
2492+ [NL80211_CHAN_WIDTH_10 ] = CMD_CBW_10MHZ ,
2493+ [NL80211_CHAN_WIDTH_20 ] = CMD_CBW_20MHZ ,
2494+ [NL80211_CHAN_WIDTH_20_NOHT ] = CMD_CBW_20MHZ ,
2495+ };
2496+
2497+ if (chandef -> width >= ARRAY_SIZE (width_to_bw ))
2498+ return 0 ;
2499+
2500+ return width_to_bw [chandef -> width ];
2501+ }
2502+
24842503int mt7615_mcu_set_chan_info (struct mt7615_phy * phy , int cmd )
24852504{
24862505 struct mt7615_dev * dev = phy -> dev ;
@@ -2521,32 +2540,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
25212540 req .switch_reason = CH_SWITCH_NORMAL ;
25222541
25232542 req .band_idx = phy != & dev -> phy ;
2524-
2525- switch (chandef -> width ) {
2526- case NL80211_CHAN_WIDTH_40 :
2527- req .bw = CMD_CBW_40MHZ ;
2528- break ;
2529- case NL80211_CHAN_WIDTH_80 :
2530- req .bw = CMD_CBW_80MHZ ;
2531- break ;
2532- case NL80211_CHAN_WIDTH_80P80 :
2533- req .bw = CMD_CBW_8080MHZ ;
2534- break ;
2535- case NL80211_CHAN_WIDTH_160 :
2536- req .bw = CMD_CBW_160MHZ ;
2537- break ;
2538- case NL80211_CHAN_WIDTH_5 :
2539- req .bw = CMD_CBW_5MHZ ;
2540- break ;
2541- case NL80211_CHAN_WIDTH_10 :
2542- req .bw = CMD_CBW_10MHZ ;
2543- break ;
2544- case NL80211_CHAN_WIDTH_20_NOHT :
2545- case NL80211_CHAN_WIDTH_20 :
2546- default :
2547- req .bw = CMD_CBW_20MHZ ;
2548- break ;
2549- }
2543+ req .bw = mt7615_mcu_chan_bw (chandef );
25502544
25512545 mt7615_mcu_set_txpower_sku (phy , req .txpower_sku );
25522546
@@ -2836,3 +2830,152 @@ int mt7615_mcu_sched_scan_enable(struct mt7615_phy *phy,
28362830 return __mt76_mcu_send_msg (& dev -> mt76 , MCU_CMD_SCHED_SCAN_ENABLE ,
28372831 & req , sizeof (req ), false);
28382832}
2833+
2834+ static int mt7615_find_freq_idx (const u16 * freqs , int n_freqs , u16 cur )
2835+ {
2836+ int i ;
2837+
2838+ for (i = 0 ; i < n_freqs ; i ++ )
2839+ if (cur == freqs [i ])
2840+ return i ;
2841+
2842+ return -1 ;
2843+ }
2844+
2845+ static int mt7615_dcoc_freq_idx (u16 freq , u8 bw )
2846+ {
2847+ static const u16 freq_list [] = {
2848+ 4980 , 5805 , 5905 , 5190 ,
2849+ 5230 , 5270 , 5310 , 5350 ,
2850+ 5390 , 5430 , 5470 , 5510 ,
2851+ 5550 , 5590 , 5630 , 5670 ,
2852+ 5710 , 5755 , 5795 , 5835 ,
2853+ 5875 , 5210 , 5290 , 5370 ,
2854+ 5450 , 5530 , 5610 , 5690 ,
2855+ 5775 , 5855
2856+ };
2857+ static const u16 freq_bw40 [] = {
2858+ 5190 , 5230 , 5270 , 5310 ,
2859+ 5350 , 5390 , 5430 , 5470 ,
2860+ 5510 , 5550 , 5590 , 5630 ,
2861+ 5670 , 5710 , 5755 , 5795 ,
2862+ 5835 , 5875
2863+ };
2864+ int offset_2g = ARRAY_SIZE (freq_list );
2865+ int idx ;
2866+
2867+ if (freq < 4000 ) {
2868+ if (freq < 2427 )
2869+ return offset_2g ;
2870+ if (freq < 2442 )
2871+ return offset_2g + 1 ;
2872+ if (freq < 2457 )
2873+ return offset_2g + 2 ;
2874+
2875+ return offset_2g + 3 ;
2876+ }
2877+
2878+ switch (bw ) {
2879+ case NL80211_CHAN_WIDTH_80 :
2880+ case NL80211_CHAN_WIDTH_80P80 :
2881+ case NL80211_CHAN_WIDTH_160 :
2882+ break ;
2883+ default :
2884+ idx = mt7615_find_freq_idx (freq_bw40 , ARRAY_SIZE (freq_bw40 ),
2885+ freq + 10 );
2886+ if (idx >= 0 ) {
2887+ freq = freq_bw40 [idx ];
2888+ break ;
2889+ }
2890+
2891+ idx = mt7615_find_freq_idx (freq_bw40 , ARRAY_SIZE (freq_bw40 ),
2892+ freq - 10 );
2893+ if (idx >= 0 ) {
2894+ freq = freq_bw40 [idx ];
2895+ break ;
2896+ }
2897+ /* fall through */
2898+ case NL80211_CHAN_WIDTH_40 :
2899+ idx = mt7615_find_freq_idx (freq_bw40 , ARRAY_SIZE (freq_bw40 ),
2900+ freq );
2901+ if (idx >= 0 )
2902+ break ;
2903+
2904+ return -1 ;
2905+
2906+ }
2907+
2908+ return mt7615_find_freq_idx (freq_list , ARRAY_SIZE (freq_list ), freq );
2909+ }
2910+
2911+ int mt7615_mcu_apply_rx_dcoc (struct mt7615_phy * phy )
2912+ {
2913+ struct mt7615_dev * dev = phy -> dev ;
2914+ struct cfg80211_chan_def * chandef = & phy -> mt76 -> chandef ;
2915+ int freq2 = chandef -> center_freq2 ;
2916+ int ret ;
2917+ struct {
2918+ u8 direction ;
2919+ u8 runtime_calibration ;
2920+ u8 _rsv [2 ];
2921+
2922+ __le16 center_freq ;
2923+ u8 bw ;
2924+ u8 band ;
2925+ u8 is_freq2 ;
2926+ u8 success ;
2927+ u8 dbdc_en ;
2928+
2929+ u8 _rsv2 ;
2930+
2931+ struct {
2932+ __le32 sx0_i_lna [4 ];
2933+ __le32 sx0_q_lna [4 ];
2934+
2935+ __le32 sx2_i_lna [4 ];
2936+ __le32 sx2_q_lna [4 ];
2937+ } dcoc_data [4 ];
2938+ } req = {
2939+ .direction = 1 ,
2940+
2941+ .bw = mt7615_mcu_chan_bw (chandef ),
2942+ .band = chandef -> center_freq1 > 4000 ,
2943+ .dbdc_en = !!dev -> mt76 .phy2 ,
2944+ };
2945+ u16 center_freq = chandef -> center_freq1 ;
2946+ int freq_idx ;
2947+ u8 * eep = dev -> mt76 .eeprom .data ;
2948+
2949+ if (!(eep [MT_EE_CALDATA_FLASH ] & MT_EE_CALDATA_FLASH_RX_CAL ))
2950+ return 0 ;
2951+
2952+ if (chandef -> width == NL80211_CHAN_WIDTH_160 ) {
2953+ freq2 = center_freq + 40 ;
2954+ center_freq -= 40 ;
2955+ }
2956+
2957+ again :
2958+ req .runtime_calibration = 1 ;
2959+ freq_idx = mt7615_dcoc_freq_idx (center_freq , chandef -> width );
2960+ if (freq_idx < 0 )
2961+ goto out ;
2962+
2963+ memcpy (req .dcoc_data , eep + MT7615_EEPROM_DCOC_OFFSET +
2964+ freq_idx * MT7615_EEPROM_DCOC_SIZE ,
2965+ sizeof (req .dcoc_data ));
2966+ req .runtime_calibration = 0 ;
2967+
2968+ out :
2969+ req .center_freq = cpu_to_le16 (center_freq );
2970+ ret = __mt76_mcu_send_msg (& dev -> mt76 , MCU_EXT_CMD_RXDCOC_CAL , & req ,
2971+ sizeof (req ), true);
2972+
2973+ if ((chandef -> width == NL80211_CHAN_WIDTH_80P80 ||
2974+ chandef -> width == NL80211_CHAN_WIDTH_160 ) && !req .is_freq2 ) {
2975+ req .is_freq2 = true;
2976+ center_freq = freq2 ;
2977+ goto again ;
2978+ }
2979+
2980+ return ret ;
2981+ }
0 commit comments