ath5k: Add debug code for EEPROM
PATCH 1/1 ath5k: Add debug code for EEPROM
* Add debug code for displaying EEPROM data. Tested on various chip combinations, on x86 and IXP43x (armv5te). It has many > 80cols warnings but i
don't think it'll be more readable if i start breaking lines, it's already messy, after all it's debug code. This code also replaces ath_info tool.
---
drivers/net/wireless/ath5k/debug.c +892 -0
@@ -324,6 +324,858 @@ static const struct file_operations fops_reset = { .owner = THIS_MODULE, }; +/* debugfs: EEPROM stuff */ + +/* EEPROM Header (common) */ +static ssize_t read_file_eeprom_header (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ + +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +char buf[2000 ]; +unsigned int len =0 ; +u16 eeprom_size; +u8 eesize; + + eesize =AR5K_REG_MS (ath5k_hw_reg_read (ah,AR5K_PCICFG ), +AR5K_PCICFG_EESIZE ); + +if (eesize ==0 ) + eeprom_size =4096 /8 ; +else if (eesize ==1 ) + eeprom_size =8192 /8 ; +else if (eesize ==2 ) + eeprom_size =16384 /8 ; +else + eeprom_size =0 ; + + len +=snprintf (buf+len,sizeof (buf)-len, +"/==============[EEPROM Information]=============\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| EEPROM Version: %1x.%1x |" , + (ee.ee_version &0xF000 ) >>12 , ee.ee_version &0xFFF ); + len +=snprintf (buf+len,sizeof (buf)-len, +" EEPROM Size: %3d kbit |\n" , eeprom_size *8 /1024 ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| EEMAP: %i |" ,AR5K_EEPROM_EEMAP (ee.ee_misc0)); + + len +=snprintf (buf+len,sizeof (buf)-len, +" Reg. Domain: 0x%02X |\n" , ee.ee_regdomain); + len +=snprintf (buf+len,sizeof (buf)-len, +"\\===============================================/\n\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"/==================[Capabilities]================\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| 802.11a Support: " ); +if (AR5K_EEPROM_HDR_11A (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" Turbo-A disabled:" ); +if (AR5K_EEPROM_HDR_T_2GHZ_DIS (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| 802.11b Support: " ); +if (AR5K_EEPROM_HDR_11B (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" Turbo-G disabled:" ); +if (AR5K_EEPROM_HDR_T_2GHZ_DIS (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| 802.11g Support: " ); +if (AR5K_EEPROM_HDR_11G (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" 2GHz XR disabled:" ); +if (AR5K_EEPROM_HDR_XR2_DIS (ee.ee_misc0)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| RFKill Support: " ); +if (AR5K_EEPROM_HDR_RFKILL (ee.ee_header)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" 5GHz XR disabled:" ); +if (AR5K_EEPROM_HDR_XR5_DIS (ee.ee_misc0)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| 32kHz Crystal: " ); +if (AR5K_EEPROM_HAS32KHZCRYSTAL (ee.ee_misc1) || +AR5K_EEPROM_HAS32KHZCRYSTAL_OLD (ee.ee_misc1)) { + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); + }else { + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + } + + len +=snprintf (buf+len,sizeof (buf)-len, +" HW Comp disabled:" ); +if (AR5K_EEPROM_COMP_DIS (ee.ee_misc5)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| AES Enc disabled: " ); +if (AR5K_EEPROM_AES_DIS (ee.ee_misc5)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" FastFrm disabled:" ); +if (AR5K_EEPROM_FF_DIS (ee.ee_misc5)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| Bursting disabled:" ); +if (AR5K_EEPROM_BURST_DIS (ee.ee_misc5)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" Max avail QCU: " ); + len +=snprintf (buf+len,sizeof (buf)-len," %3i |\n" , +AR5K_EEPROM_MAX_QCU (ee.ee_misc5)); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| Heavy Clip enable:" ); +if (AR5K_EEPROM_HEAVY_CLIP_EN (ee.ee_misc5)) + len +=snprintf (buf+len,sizeof (buf)-len," yes |" ); +else + len +=snprintf (buf+len,sizeof (buf)-len," no |" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +" Keycache size: " ); + len +=snprintf (buf+len,sizeof (buf)-len," %3i |\n" , +AR5K_EEPROM_KEY_CACHE_SIZE (ee.ee_misc5)); + + len +=snprintf (buf+len,sizeof (buf)-len, +"\\================================================/\n\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"/====[Calibration data common for all modes]====\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| |\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| CCK/OFDM gain delta: %2i |\n" , + ee.ee_cck_ofdm_gain_delta); + len +=snprintf (buf+len,sizeof (buf)-len, +"| CCK/OFDM power delta: %2i |\n" , + ee.ee_cck_ofdm_power_delta); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Scaled CCK delta: %2i |\n" , + ee.ee_scaled_cck_delta); + len +=snprintf (buf+len,sizeof (buf)-len, +"| 2GHz Antenna gain: %2i |\n" , +AR5K_EEPROM_ANT_GAIN_2GHZ (ee.ee_ant_gain)); + len +=snprintf (buf+len,sizeof (buf)-len, +"| 5GHz Antenna gain: %2i |\n" , +AR5K_EEPROM_ANT_GAIN_5GHZ (ee.ee_ant_gain)); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Turbo 2W maximum dBm: %2i |\n" , +AR5K_EEPROM_HDR_T_5GHZ_DBM (ee.ee_header)); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Target power start: 0x%03x |\n" , +AR5K_EEPROM_TARGET_PWRSTART (ee.ee_misc1)); + len +=snprintf (buf+len,sizeof (buf)-len, +"| EAR Start: 0x%03x |\n" , +AR5K_EEPROM_EARSTART (ee.ee_misc0)); + len +=snprintf (buf+len,sizeof (buf)-len, +"| |\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"\\===============================================/\n" ); + + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); + +return len; +} + +static const struct file_operations fops_ee_header = { + .read = read_file_eeprom_header, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +/* EEPROM Header (per mode) */ +static unsigned int dump_calinfo_for_mode (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +unsigned int len =0 ; +char buf[2000 ]; +int i; + +if ((!AR5K_EEPROM_HDR_11A (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11A )) + || (!AR5K_EEPROM_HDR_11B (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11B )) + || (!AR5K_EEPROM_HDR_11G (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11G ))) { + len +=snprintf (buf+len,sizeof (buf)-len, +"Mode not available for your card\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; + } + + + len +=snprintf (buf+len,sizeof (buf)-len, +"/=========================================================\\\n" ); + +if (mode ==AR5K_EEPROM_MODE_11A ) + len +=snprintf (buf+len,sizeof (buf)-len, +"| Calibration data for 802.11a |\n" ); + +if (mode ==AR5K_EEPROM_MODE_11B ) + len +=snprintf (buf+len,sizeof (buf)-len, +"| Calibration data for 802.11b |\n" ); + +if (mode ==AR5K_EEPROM_MODE_11G ) + len +=snprintf (buf+len,sizeof (buf)-len, +"| Calibration data for 802.11g |\n" ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"|=========================================================|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| I power: 0x%02x | Q power: 0x%02x |\n" , + ee.ee_i_cal[mode], ee.ee_q_cal[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Use fixed bias: 0x%02x | Max turbo power: 0x%02x |\n" , + ee.ee_fixed_bias[mode], ee.ee_turbo_max_power[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Max XR power: 0x%02x | Switch Settling Time: 0x%02x |\n" , + ee.ee_xr_power[mode], ee.ee_switch_settling[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Tx/Rx attenuation: 0x%02x | TX end to XLNA On: 0x%02x |\n" , + ee.ee_atn_tx_rx[mode], ee.ee_tx_end2xlna_enable[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| TX end to XPA Off: 0x%02x | TX end to XPA On: 0x%02x |\n" , + ee.ee_tx_end2xpa_disable[mode], ee.ee_tx_frm2xpa_enable[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| 62db Threshold: 0x%02x | XLNA gain: 0x%02x |\n" , + ee.ee_thr_62[mode], ee.ee_xlna_gain[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| XPD: 0x%02x | XPD gain: 0x%02x |\n" , + ee.ee_xpd[mode], ee.ee_x_gain[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| I gain: 0x%02x | Tx/Rx margin: 0x%02x |\n" , + ee.ee_i_gain[mode], ee.ee_margin_tx_rx[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| False detect backoff: 0x%02x | Noise Floor Threshold: %3d |\n" , + ee.ee_false_detect[mode], ee.ee_noise_floor_thr[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| ADC desired size: %3d | PGA desired size: %3d |\n" , + ee.ee_adc_desired_size[mode], ee.ee_pga_desired_size[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"|=========================================================|\n" ); +for (i =0 ; i <AR5K_EEPROM_N_PCDAC ; i++) { + len +=snprintf (buf+len,sizeof (buf)-len, +"| Antenna control %2i: 0x%02x |" , i, + ee.ee_ant_control[mode][i]); + i++; + len +=snprintf (buf+len,sizeof (buf)-len, +" Antenna control %2i: 0x%02x |\n" , i, + ee.ee_ant_control[mode][i]); + } + len +=snprintf (buf+len,sizeof (buf)-len, +"|=========================================================|\n" ); +for (i =0 ; i <AR5K_EEPROM_N_OBDB ; i++) { + len +=snprintf (buf+len,sizeof (buf)-len, +"| Output Bias current %i: %2i |" , i, + ee.ee_ob[mode][i]); + len +=snprintf (buf+len,sizeof (buf)-len, +" Driver Bias current %i: %2i |\n" , i, + ee.ee_db[mode][i]); + } + len +=snprintf (buf+len,sizeof (buf)-len, +"\\=========================================================/\n" ); + +if (ee.ee_version >=AR5K_EEPROM_VERSION_5_0 && + (mode ==AR5K_EEPROM_MODE_11A || mode ==AR5K_EEPROM_MODE_11G )) { + len +=snprintf (buf+len,sizeof (buf)-len, +"/==================== Turbo mode infos ===================\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Switch Settling time: 0x%02x | Tx/Rx margin: 0x%02x |\n" , + ee.ee_switch_settling_turbo[mode], ee.ee_margin_tx_rx_turbo[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Tx/Rx attenuation: 0x%02x | ADC desired size: %3d |\n" , + ee.ee_atn_tx_rx_turbo[mode], ee.ee_adc_desired_size_turbo[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"| PGA desired size: %3d | |\n" , + ee.ee_pga_desired_size_turbo[mode]); + len +=snprintf (buf+len,sizeof (buf)-len, +"\\=========================================================/\n" ); + } + + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; +} + +static ssize_t read_file_eeprom_header_11a (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11A , user_buf, count, ppos); +return len; +} + +static ssize_t read_file_eeprom_header_11b (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11B , user_buf, count, ppos); +return len; +} + +static ssize_t read_file_eeprom_header_11g (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11G , user_buf, count, ppos); +return len; +} + +static const struct file_operations fops_ee_header_11a = { + .read = read_file_eeprom_header_11a, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_header_11b = { + .read = read_file_eeprom_header_11b, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_header_11g = { + .read = read_file_eeprom_header_11g, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + + +/* EEPROM channel power calibration info (per mode) */ +static unsigned int dump_pcalinfo_for_mode_rf5111 (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_chan_pcal_info *gen_chan_info; +struct ath5k_chan_pcal_info_rf5111 *chan_pcal_info; +unsigned int len =0 ; +char buf[4000 ]; +u_int16_t cal_piers; +int i, c; + +if ((!AR5K_EEPROM_HDR_11A (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11A )) + || (!AR5K_EEPROM_HDR_11B (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11B )) + || (!AR5K_EEPROM_HDR_11G (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11G ))) { + len +=snprintf (buf+len,sizeof (buf)-len, +"Mode not available for your card\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; + } + +switch (mode) { +case AR5K_EEPROM_MODE_11A : + gen_chan_info = ee.ee_pwr_cal_a; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11B : + gen_chan_info = ee.ee_pwr_cal_b; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11G : + gen_chan_info = ee.ee_pwr_cal_g; + cal_piers = ee.ee_n_piers[mode]; +break ; +default : +return len; + } + + len +=snprintf (buf+len,sizeof (buf)-len, +"/=============================== Per channel power calibration ================================\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 | pwr_4 | pwr_5 | pwr_6 | pwr_7 | pwr_8 | pwr_9 | pwr10 |\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |\n" ); + +for (i =0 ; i < cal_piers; i++) { + chan_pcal_info = &gen_chan_info[i].rf5111_info; + + len +=snprintf (buf+len,sizeof (buf)-len, +"|======|=======|=======|=======|=======|=======|=======|=======|=======|=======|=======|=======|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| %4i |" , gen_chan_info[i].freq); +if (ee.ee_version <=AR5K_EEPROM_VERSION_3_3 ) { +for (c =0 ; c <AR5K_EEPROM_N_PWR_POINTS_5111 ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , chan_pcal_info->pwr[c] /2 , + chan_pcal_info->pwr[c] %2 *50 ); + } + + len +=snprintf (buf+len,sizeof (buf)-len,"\n| |" ); + }else { +for (c =0 ; c <AR5K_EEPROM_N_PWR_POINTS_5111 ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , chan_pcal_info->pwr[c] /4 , + chan_pcal_info->pwr[c] %4 *25 ); + } + + len +=snprintf (buf+len,sizeof (buf)-len,"\n| |" ); + } + +for (c =0 ; c <AR5K_EEPROM_N_PWR_POINTS_5111 ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len," [%2i]" , + chan_pcal_info->pcdac[c]); + len +=snprintf (buf+len,sizeof (buf)-len," |" ); + } + + len +=snprintf (buf+len,sizeof (buf)-len,"\n" ); + + } + + len +=snprintf (buf+len,sizeof (buf)-len, +"\\==============================================================================================/\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; +} + +static unsigned int dump_pcalinfo_for_mode_rf5112 (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_chan_pcal_info *gen_chan_info; +struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; +unsigned int len =0 ; +char buf[4000 ]; +u_int16_t cal_piers; +int i, c; + +if ((!AR5K_EEPROM_HDR_11A (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11A )) + || (!AR5K_EEPROM_HDR_11B (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11B )) + || (!AR5K_EEPROM_HDR_11G (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11G ))) { + len +=snprintf (buf+len,sizeof (buf)-len, +"Mode not available for your card\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; + } + +switch (mode) { +case AR5K_EEPROM_MODE_11A : + gen_chan_info = ee.ee_pwr_cal_a; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11B : + gen_chan_info = ee.ee_pwr_cal_b; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11G : + gen_chan_info = ee.ee_pwr_cal_g; + cal_piers = ee.ee_n_piers[mode]; +break ; +default : +return len; + } + + len +=snprintf (buf+len,sizeof (buf)-len, +"/=================== Per channel power calibration ====================\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | |\n" ); + +for (i =0 ; i < cal_piers; i++) { + + chan_pcal_info = &gen_chan_info[i].rf5112_info; + + len +=snprintf (buf+len,sizeof (buf)-len, +"|======|=======|=======|=======|=======|=======|=======|=======|=======|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| %4i |" , gen_chan_info[i].freq); + +for (c =0 ; c <AR5K_EEPROM_N_XPD0_POINTS ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , chan_pcal_info->pwr_x0[c] /4 , + chan_pcal_info->pwr_x0[c] %4 *25 ); + } + +for (c =0 ; c <AR5K_EEPROM_N_XPD3_POINTS ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , chan_pcal_info->pwr_x3[c] /4 , + chan_pcal_info->pwr_x3[c] %4 *25 ); + } + + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |\n" , gen_chan_info[i].max_pwr /4 , + gen_chan_info[i].max_pwr %4 *25 ); + + len +=snprintf (buf+len,sizeof (buf)-len,"| |" ); + +for (c =0 ; c <AR5K_EEPROM_N_XPD0_POINTS ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len," [%2i]" , + chan_pcal_info->pcdac_x0[c]); + len +=snprintf (buf+len,sizeof (buf)-len, +" |" ); + } + +for (c =0 ; c <AR5K_EEPROM_N_XPD3_POINTS ; c++) { + len +=snprintf (buf+len,sizeof (buf)-len," [%2i]" , + chan_pcal_info->pcdac_x3[c]); + len +=snprintf (buf+len,sizeof (buf)-len, +" |" ); + } + + len +=snprintf (buf+len,sizeof (buf)-len," |\n" ); + + } + len +=snprintf (buf+len,sizeof (buf)-len, +"\\======================================================================/\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; +} + +static unsigned int dump_pcalinfo_for_mode_rf2413 (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_chan_pcal_info *gen_chan_info; +struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info; +unsigned int len =0 ; +char buf[4000 ]; +u_int16_t cal_piers; +int i, c; + +if ((!AR5K_EEPROM_HDR_11A (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11A )) + || (!AR5K_EEPROM_HDR_11B (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11B )) + || (!AR5K_EEPROM_HDR_11G (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11G ))) { + len +=snprintf (buf+len,sizeof (buf)-len, +"Mode not available for your card\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; + } + +switch (mode) { +case AR5K_EEPROM_MODE_11A : + gen_chan_info = ee.ee_pwr_cal_a; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11B : + gen_chan_info = ee.ee_pwr_cal_b; + cal_piers = ee.ee_n_piers[mode]; +break ; +case AR5K_EEPROM_MODE_11G : + gen_chan_info = ee.ee_pwr_cal_g; + cal_piers = ee.ee_n_piers[mode]; +break ; +default : +return len; + } + + len +=snprintf (buf+len,sizeof (buf)-len, +"/====================== Per channel power calibration ===================\\\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| Freq | pwr_i | pwr_0 | pwr_1 | pwr_2 | pwr_3 |\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| | pddac_i | pddac_0 | pddac_1 | pddac_2 | pddac_3 |\n" ); + +for (i =0 ; i < cal_piers; i++) { + + chan_pcal_info = &gen_chan_info[i].rf2413_info; + + len +=snprintf (buf+len,sizeof (buf)-len, +"|======|=========|=============|=============|=============|=============|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| %4i | | | | | |\n" , + gen_chan_info[i].freq); + len +=snprintf (buf+len,sizeof (buf)-len, +"|------|---------|-------------|-------------|-------------|-------------|\n" ); +for (c =0 ; c < ee.ee_pd_gains[mode]; c++) { + len +=snprintf (buf+len,sizeof (buf)-len, +"| | %2i | %2i.%02i | %2i.%02i | %2i.%02i | %2i.%02i |\n" , + chan_pcal_info->pwr_i[c], + chan_pcal_info->pwr[c][0 ] /2 , + chan_pcal_info->pwr[c][0 ] %2 *50 , + chan_pcal_info->pwr[c][1 ] /2 , + chan_pcal_info->pwr[c][1 ] %2 *50 , + chan_pcal_info->pwr[c][2 ] /2 , + chan_pcal_info->pwr[c][2 ] %2 *50 , + chan_pcal_info->pwr[c][3 ] /2 , + chan_pcal_info->pwr[c][3 ] %2 *50 ); + + len +=snprintf (buf+len,sizeof (buf)-len, +"| | %3i | %3i | %3i | %3i | %3i |\n" , + chan_pcal_info->pddac_i[c], + chan_pcal_info->pddac[c][0 ], + chan_pcal_info->pddac[c][1 ], + chan_pcal_info->pddac[c][2 ], + chan_pcal_info->pddac[c][3 ]); + +if (c < ee.ee_pd_gains[mode] -1 ) + len +=snprintf (buf+len,sizeof (buf)-len, +"|------|---------|-------------|-------------|-------------|-------------|\n" ); + } + } + len +=snprintf (buf+len,sizeof (buf)-len, +"\\========================================================================/\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; +} + +static ssize_t read_file_eeprom_pcalinfo_11a (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + +switch (ah->ah_radio) { +case AR5K_RF5111 : + len =dump_pcalinfo_for_mode_rf5111 (ah,AR5K_EEPROM_MODE_11A , + user_buf, count, ppos); +break ; +case AR5K_RF5112 : + len =dump_pcalinfo_for_mode_rf5112 (ah,AR5K_EEPROM_MODE_11A , + user_buf, count, ppos); +break ; +case AR5K_RF2413 : +case AR5K_RF5413 : +case AR5K_RF2425 : + len =dump_pcalinfo_for_mode_rf2413 (ah,AR5K_EEPROM_MODE_11A , + user_buf, count, ppos); +break ; +default : +return 0 ; + } + +return len; +} + +static ssize_t read_file_eeprom_pcalinfo_11b (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + +switch (ah->ah_radio) { +case AR5K_RF5111 : + len =dump_pcalinfo_for_mode_rf5111 (ah,AR5K_EEPROM_MODE_11B , user_buf, count, ppos); +break ; +case AR5K_RF5112 : + len =dump_pcalinfo_for_mode_rf5112 (ah,AR5K_EEPROM_MODE_11B , user_buf, count, ppos); +break ; +case AR5K_RF2413 : +case AR5K_RF5413 : +case AR5K_RF2425 : + len =dump_pcalinfo_for_mode_rf2413 (ah,AR5K_EEPROM_MODE_11B , user_buf, count, ppos); +break ; +default : +return 0 ; + } + +return len; +} + +static ssize_t read_file_eeprom_pcalinfo_11g (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + +switch (ah->ah_radio) { +case AR5K_RF5111 : + len =dump_pcalinfo_for_mode_rf5111 (ah,AR5K_EEPROM_MODE_11G , user_buf, count, ppos); +break ; +case AR5K_RF5112 : + len =dump_pcalinfo_for_mode_rf5112 (ah,AR5K_EEPROM_MODE_11G , user_buf, count, ppos); +break ; +case AR5K_RF2413 : +case AR5K_RF5413 : +case AR5K_RF2425 : + len =dump_pcalinfo_for_mode_rf2413 (ah,AR5K_EEPROM_MODE_11G , user_buf, count, ppos); +break ; +default : +return 0 ; + } + +return len; +} + +static const struct file_operations fops_ee_pcalinfo_11a = { + .read = read_file_eeprom_pcalinfo_11a, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_pcalinfo_11b = { + .read = read_file_eeprom_pcalinfo_11b, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_pcalinfo_11g = { + .read = read_file_eeprom_pcalinfo_11g, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +/* EEPROM Per rate power calibration info */ +static unsigned int dump_rate_calinfo_for_mode (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_rate_pcal_info *rate_pcal_info; +u_int16_t rate_target_pwr_num; +unsigned int len =0 ; +char buf[2000 ]; +int i; + +if ((!AR5K_EEPROM_HDR_11A (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11A )) + || (!AR5K_EEPROM_HDR_11B (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11B )) + || (!AR5K_EEPROM_HDR_11G (ee.ee_header) && (mode ==AR5K_EEPROM_MODE_11G ))) { + len +=snprintf (buf+len,sizeof (buf)-len, +"Mode not available for your card\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; + } + +switch (mode) { +case AR5K_EEPROM_MODE_11A : + rate_pcal_info = ee.ee_rate_tpwr_a; + rate_target_pwr_num = ee.ee_rate_target_pwr_num[mode]; +break ; +case AR5K_EEPROM_MODE_11B : + rate_pcal_info = ee.ee_rate_tpwr_b; + rate_target_pwr_num = ee.ee_rate_target_pwr_num[mode]; +break ; +case AR5K_EEPROM_MODE_11G : + rate_pcal_info = ee.ee_rate_tpwr_g; + rate_target_pwr_num = ee.ee_rate_target_pwr_num[mode]; +break ; +default : +return 0 ; + } + + len +=snprintf (buf+len,sizeof (buf)-len, +"/============== Per rate power calibration ===========\\\n" ); +if (mode ==AR5K_EEPROM_MODE_11B ) + len +=snprintf (buf+len,sizeof (buf)-len, +"| Freq | 1Mbit/s | 2Mbit/s | 5.5Mbit/s | 11Mbit/s |\n" ); +else + len +=snprintf (buf+len,sizeof (buf)-len, +"| Freq | 6-24Mbit/s | 36Mbit/s | 48Mbit/s | 54Mbit/s |\n" ); + +for (i =0 ; i < rate_target_pwr_num; i++) { + + len +=snprintf (buf+len,sizeof (buf)-len, +"|======|============|==========|===========|==========|\n" ); + len +=snprintf (buf+len,sizeof (buf)-len, +"| %4i |" , rate_pcal_info[i].freq); + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , rate_pcal_info[i].target_power_6to24 /2 , + rate_pcal_info[i].target_power_6to24 %2 ); + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , rate_pcal_info[i].target_power_36 /2 , + rate_pcal_info[i].target_power_36 %2 ); + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |" , rate_pcal_info[i].target_power_48 /2 , + rate_pcal_info[i].target_power_48 %2 ); + len +=snprintf (buf+len,sizeof (buf)-len, +" %2i.%02i |\n" , rate_pcal_info[i].target_power_54 /2 , + rate_pcal_info[i].target_power_54 %2 ); + } + len +=snprintf (buf+len,sizeof (buf)-len, +"\\=====================================================/\n" ); + len =simple_read_from_buffer (user_buf, count, ppos, buf, len); +return len; +} + +static ssize_t read_file_rate_pcalinfo_11a (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_rate_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11A , user_buf, count, ppos); +return len; +} + +static ssize_t read_file_rate_pcalinfo_11b (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_rate_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11B , user_buf, count, ppos); +return len; +} + +static ssize_t read_file_rate_pcalinfo_11g (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +unsigned int len =0 ; + + len =dump_rate_calinfo_for_mode (ah,AR5K_EEPROM_MODE_11G , user_buf, count, ppos); +return len; +} + +static const struct file_operations fops_ee_rate_pcalinfo_11a = { + .read = read_file_rate_pcalinfo_11a, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_rate_pcalinfo_11b = { + .read = read_file_rate_pcalinfo_11b, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +}; + +static const struct file_operations fops_ee_rate_pcalinfo_11g = { + .read = read_file_rate_pcalinfo_11g, + .open = ath5k_debugfs_open, + .owner =THIS_MODULE , +};/* debugfs: debug level */
@@ -426,6 +1278,36 @@ ath5k_debug_init_device(struct ath5k_softc *sc) sc->debug.debugfs_tsf =debugfs_create_file ("tsf" ,S_IWUSR |S_IRUGO , sc->debug.debugfs_phydir, sc, &fops_tsf); + sc->debug.debugfs_ee_header =debugfs_create_file ("eeprom_header" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_header); + + sc->debug.debugfs_ee_header_11a =debugfs_create_file ("eeprom_header_11a" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_header_11a); + + sc->debug.debugfs_ee_header_11b =debugfs_create_file ("eeprom_header_11b" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_header_11b); + + sc->debug.debugfs_ee_header_11g =debugfs_create_file ("eeprom_header_11g" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_header_11g); + + sc->debug.debugfs_ee_pcalinfo_11a =debugfs_create_file ("eeprom_chan_pcalinfo_11a" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_pcalinfo_11a); + + sc->debug.debugfs_ee_pcalinfo_11b =debugfs_create_file ("eeprom_chan_pcalinfo_11b" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_pcalinfo_11b); + + sc->debug.debugfs_ee_pcalinfo_11g =debugfs_create_file ("eeprom_chan_pcalinfo_11g" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_pcalinfo_11g); + + sc->debug.debugfs_ee_rate_pcalinfo_11a =debugfs_create_file ("eeprom_rate_pcalinfo_11a" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_rate_pcalinfo_11a); + + sc->debug.debugfs_ee_rate_pcalinfo_11b =debugfs_create_file ("eeprom_rate_pcalinfo_11b" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_rate_pcalinfo_11b); + + sc->debug.debugfs_ee_rate_pcalinfo_11g =debugfs_create_file ("eeprom_rate_pcalinfo_11g" ,S_IRUGO , + sc->debug.debugfs_phydir, sc, &fops_ee_rate_pcalinfo_11g); + sc->debug.debugfs_beacon =debugfs_create_file ("beacon" ,S_IWUSR |S_IRUGO , sc->debug.debugfs_phydir, sc, &fops_beacon);
@@ -446,6 +1328,16 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)debugfs_remove (sc->debug.debugfs_registers);debugfs_remove (sc->debug.debugfs_tsf);debugfs_remove (sc->debug.debugfs_beacon); +debugfs_remove (sc->debug.debugfs_ee_header); +debugfs_remove (sc->debug.debugfs_ee_header_11a); +debugfs_remove (sc->debug.debugfs_ee_header_11b); +debugfs_remove (sc->debug.debugfs_ee_header_11g); +debugfs_remove (sc->debug.debugfs_ee_pcalinfo_11a); +debugfs_remove (sc->debug.debugfs_ee_pcalinfo_11b); +debugfs_remove (sc->debug.debugfs_ee_pcalinfo_11g); +debugfs_remove (sc->debug.debugfs_ee_rate_pcalinfo_11a); +debugfs_remove (sc->debug.debugfs_ee_rate_pcalinfo_11b); +debugfs_remove (sc->debug.debugfs_ee_rate_pcalinfo_11g);debugfs_remove (sc->debug.debugfs_reset);debugfs_remove (sc->debug.debugfs_phydir); }
drivers/net/wireless/ath5k/debug.h +10 -0
@@ -73,6 +73,16 @@ struct ath5k_dbg_info {struct dentry *debugfs_debug;struct dentry *debugfs_registers;struct dentry *debugfs_tsf; +struct dentry *debugfs_ee_header; +struct dentry *debugfs_ee_header_11a; +struct dentry *debugfs_ee_header_11b; +struct dentry *debugfs_ee_header_11g; +struct dentry *debugfs_ee_pcalinfo_11a; +struct dentry *debugfs_ee_pcalinfo_11b; +struct dentry *debugfs_ee_pcalinfo_11g; +struct dentry *debugfs_ee_rate_pcalinfo_11a; +struct dentry *debugfs_ee_rate_pcalinfo_11b; +struct dentry *debugfs_ee_rate_pcalinfo_11g;struct dentry *debugfs_beacon;struct dentry *debugfs_reset; };
Quoted 2 lines · Nick Kossifidis
* Add debug code for displaying EEPROM data. Tested on various chip combinations, on x86 and IXP43x (armv5te). It has many > 80cols warnings but i
don't think it'll be more readable if i start breaking lines, it's already messy, after all it's debug code. This code also replacesath_infotool.
I think breaking lines in this case would be rather contraproductive.
Quoted 12 lines
Signed-off-by Nick Kossifidis <[email protected]>---
drivers/net/wireless/ath5k/debug.c +1
-0@@ -324,6 +324,858 @@ static const struct file_operations fops_reset = { .owner = THIS_MODULE, }; +/* debugfs: EEPROM stuff */
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 337
Quoted 10 lines
drivers/net/wireless/ath5k/debug.c +10
-0+ +/* EEPROM Header (common) */ +static ssize_t read_file_eeprom_header (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ + +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +char buf[2000 ];
Please don't use that much memory from stack. 2k is way too much. Note that you use yet another bunch of stack (next 3k here on 64-bit) by ath5k_eeprom_info and 32-bit x86 can still be configured with 4k stacks.
Convert both of them to dynamically allocated buffers.
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 535
Quoted 7 lines
drivers/net/wireless/ath5k/debug.c +7
-0+/* EEPROM Header (per mode) */ +static unsigned int dump_calinfo_for_mode (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +unsigned int len =0 ; +char buf[2000 ];
dtto
Quoted 1 line
drivers/net/wireless/ath5k/debug.c +1
-0+int i;
...
drivers/net/wireless/ath5k/debug.c
Quoted 1 line
drivers/net/wireless/ath5k/debug.c +1
-0+ len =simple_read_from_buffer (user_buf, count, ppos, buf, len);
simple_read_from_buffer can fail and returns negative errno in that case, change dump_calinfo_for_mode return type appropriately.
Quoted 2 lines
drivers/net/wireless/ath5k/debug.c +2
-0+return len; +}
...
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 694
Quoted 3 lines
drivers/net/wireless/ath5k/debug.c +3
-0+/* EEPROM channel power calibration info (per mode) */ +static unsigned int dump_pcalinfo_for_mode_rf5111 (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos)
return ssize_t for the same reason
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 700
Quoted 6 lines
drivers/net/wireless/ath5k/debug.c +6
-0+{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_chan_pcal_info *gen_chan_info; +struct ath5k_chan_pcal_info_rf5111 *chan_pcal_info; +unsigned int len =0 ; +char buf[4000 ];
Here you are almost out of stack even on 8k stacks ;).
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 779
Quoted 2 lines
drivers/net/wireless/ath5k/debug.c +2
-0+static unsigned int dump_pcalinfo_for_mode_rf5112 (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos)
dtto and further too
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 785
Quoted 6 lines
drivers/net/wireless/ath5k/debug.c +6
-0+{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +struct ath5k_chan_pcal_info *gen_chan_info; +struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; +unsigned int len =0 ; +char buf[4000 ];
dtto and further too
Happy new year!
Hello Jiri and thanks a lot for the review ;-)
2009/1/4 Jiri Slaby <[email protected]>:
Quoted 16 lines
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 337
Quoted 11 lines
drivers/net/wireless/ath5k/debug.c +11
-0+/* debugfs: EEPROM stuff */ + +/* EEPROM Header (common) */ +static ssize_t read_file_eeprom_header (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ + +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +char buf[2000 ];Please don't use that much memory from stack. 2k is way too much. Note that you use yet another bunch of stack (next 3k here on 64-bit) by
ath5k_eeprom_infoand 32-bit x86 can still be configured with 4k stacks.
Quoted 2 lines
Convert both of them to dynamically allocated buffers.
Why dynamically allocated buffers (can you point out some docs on these please ?) ? The length of each file (what we print) is standard. I understand that we use too much stack here but we can work this out eg. by using a pointer to ath5k_eeprom_info or something like that. I checked out user_buffer btw and it's 4K, sometimes it's not much for calibration data (eg. on RF5111 that we have 10 points per pd gain curve or RF2413+ that we can have multiple pd gain curves per channel).
Quoted 10 lines
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 535
Quoted 7 lines
drivers/net/wireless/ath5k/debug.c +7
-0+/* EEPROM Header (per mode) */ +static unsigned int dump_calinfo_for_mode (struct ath5k_hw *ah,int mode, +char __user *user_buf,size_t count,loff_t *ppos) +{ +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +unsigned int len =0 ; +char buf[2000 ];dtto
What does dtto mean ?
Quoted 7 lines
Quoted 1 line
+ int i;
...
Quoted 1 line
+ len =
simple_read_from_buffer(user_buf, count, ppos, buf, len);
simple_read_from_buffercan fail and returns negative errno in that case, changedump_calinfo_for_modereturn type appropriately.
ACK
Quoted 1 line
Happy new year!
Thank you verry much, happy new year !! ;-)
Signature · 3 lines
GPG ID: 0xD21DB2DB As you read this post global entropy rises. Have Fun ;-) Nick
Quoted 8 lines · Nick Kossifidis
Quoted 6 lines
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 535
Quoted 3 lines
drivers/net/wireless/ath5k/debug.c +3
-0+struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +unsigned int len =0 ; +char buf[2000 ];dtto
What does dtto mean ?
A typo from ditto:
Quoted 1 line
From WordNet (r) 3.0 (2006) [wn]:
ditto
n 1: a mark used to indicate the word above it should be
repeated [syn: {ditto mark}, {ditto}]
v 1: repeat an action or statement; "The next speaker dittoed
her argument"
Signature · 1 line
Kalle Valo
Nick Kossifidis napsal(a):
Quoted 18 lines
Hello Jiri and thanks a lot for the review ;-)
2009/1/4 Jiri Slaby <[email protected]>:
Quoted 15 lines
drivers/net/wireless/ath5k/debug.c static const struct file_operations fops_reset = { · line 337
Quoted 11 lines
drivers/net/wireless/ath5k/debug.c +11
-0+/* debugfs: EEPROM stuff */ + +/* EEPROM Header (common) */ +static ssize_t read_file_eeprom_header (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ + +struct ath5k_softc *sc = file->private_data; +struct ath5k_hw *ah = sc->ah; +struct ath5k_eeprom_info ee = ah->ah_capabilities.cap_eeprom; +char buf[2000 ];Please don't use that much memory from stack. 2k is way too much. Note that you use yet another bunch of stack (next 3k here on 64-bit) by
ath5k_eeprom_infoand 32-bit x86 can still be configured with 4k stacks.
Quoted 7 lines
Quoted 2 lines
Convert both of them to dynamically allocated buffers.
Why dynamically allocated buffers (can you point out some docs on these please ?) ? The length of each file (what we print) is standard. I understand that we use too much stack here but we can work this out eg. by using a pointer to
ath5k_eeprom_infoor something like that.
Yes, no problem in changing it to a pointer. Anyway the buf should be kmalloc'ed anyway.
Quoted 5 lines
I
checked outuser_bufferbtw and it's 4K, sometimes it's not much for calibration data (eg. on RF5111 that we have 10 points per pd gain curve or RF2413+ that we can have multiple pd gain curves per channel).
I don't understand here. user_buf is sized by userspace application. E.g. cat on my system requests user_buf of size 1K. simple_read_from_buffer() takes care about multiple invocations of fops.read function by looking at ppos parameter and filling user_buf by correct contents (some offset in from param). BTW as a side-effect, it is possible, that the user will get different info in these split reads.
Quoted 4 lines
Quoted 2 lines
dtto
What does dtto mean ?
Oops, as I checked right now, this shortcut is commonly used only in czech. It should be detto or ditto (and it means "the same as above"), sorry for the confusion.