All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ath5k: Add debug code for EEPROM
@ 2009-01-04 17:32 Nick Kossifidis
  2009-01-04 19:31 ` Jiri Slaby
  0 siblings, 1 reply; 5+ messages in thread
From: Nick Kossifidis @ 2009-01-04 17:32 UTC (permalink / raw)
  To: ath5k-devel, linux-wireless; +Cc: linville, jirislaby, mcgrof, me, nbd

 * 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.

Signed-Off-by: Nick Kossifidis <mickflemm@gmail.com>

---
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index ccaeb5c..f0ef5b3 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -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);
 }
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index ffc5293..c5c88d8 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -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;
 };


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] ath5k: Add debug code for EEPROM
  2009-01-04 17:32 [PATCH] ath5k: Add debug code for EEPROM Nick Kossifidis
@ 2009-01-04 19:31 ` Jiri Slaby
  2009-01-10  0:37   ` [ath5k-devel] " Nick Kossifidis
  0 siblings, 1 reply; 5+ messages in thread
From: Jiri Slaby @ 2009-01-04 19:31 UTC (permalink / raw)
  To: ath5k-devel, linux-wireless, linville, jirislaby, mcgrof, me, nbd

Nick Kossifidis wrote:
>  * 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.

I think breaking lines in this case would be rather contraproductive.

> Signed-Off-by: Nick Kossifidis <mickflemm@gmail.com>
> 
> ---
> diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
> index ccaeb5c..f0ef5b3 100644
> --- a/drivers/net/wireless/ath5k/debug.c
> +++ b/drivers/net/wireless/ath5k/debug.c
> @@ -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];

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.

> +/* 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

> +	int i;
...
> +	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.

> +	return len;
> +}
...
> +/* 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

> +{
> +	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 ;).

> +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

> +{
> +	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!

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ath5k-devel] [PATCH] ath5k: Add debug code for EEPROM
  2009-01-04 19:31 ` Jiri Slaby
@ 2009-01-10  0:37   ` Nick Kossifidis
  2009-01-10  6:28     ` Kalle Valo
  2009-01-10 14:35     ` Jiri Slaby
  0 siblings, 2 replies; 5+ messages in thread
From: Nick Kossifidis @ 2009-01-10  0:37 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: ath5k-devel, linux-wireless, linville, mcgrof, me, nbd

Hello Jiri and thanks a lot for the review ;-)

2009/1/4 Jiri Slaby <jirislaby@gmail.com>:
>> +/* 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_info and 32-bit x86 can still be configured with 4k stacks.
>
> 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).

>> +/* 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 ?

>> +     int i;
> ...
>> +     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.
>

ACK

> Happy new year!

Thank you verry much, happy new year !! ;-)



-- 
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ath5k-devel] [PATCH] ath5k: Add debug code for EEPROM
  2009-01-10  0:37   ` [ath5k-devel] " Nick Kossifidis
@ 2009-01-10  6:28     ` Kalle Valo
  2009-01-10 14:35     ` Jiri Slaby
  1 sibling, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2009-01-10  6:28 UTC (permalink / raw)
  To: Nick Kossifidis
  Cc: Jiri Slaby, ath5k-devel, linux-wireless, linville, mcgrof, me, nbd

"Nick Kossifidis" <mickflemm@gmail.com> writes:

>>> +     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:

>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"


-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ath5k-devel] [PATCH] ath5k: Add debug code for EEPROM
  2009-01-10  0:37   ` [ath5k-devel] " Nick Kossifidis
  2009-01-10  6:28     ` Kalle Valo
@ 2009-01-10 14:35     ` Jiri Slaby
  1 sibling, 0 replies; 5+ messages in thread
From: Jiri Slaby @ 2009-01-10 14:35 UTC (permalink / raw)
  To: Nick Kossifidis; +Cc: ath5k-devel, linux-wireless, linville, mcgrof, me, nbd

Nick Kossifidis napsal(a):
> Hello Jiri and thanks a lot for the review ;-)
> 
> 2009/1/4 Jiri Slaby <jirislaby@gmail.com>:
>>> +/* 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_info and 32-bit x86 can still be configured with 4k stacks.
>>
>> 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.

Yes, no problem in changing it to a pointer. Anyway the buf should be
kmalloc'ed anyway.

> 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).

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.

>> 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.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-01-10 14:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-04 17:32 [PATCH] ath5k: Add debug code for EEPROM Nick Kossifidis
2009-01-04 19:31 ` Jiri Slaby
2009-01-10  0:37   ` [ath5k-devel] " Nick Kossifidis
2009-01-10  6:28     ` Kalle Valo
2009-01-10 14:35     ` Jiri Slaby

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.