⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zd_chip.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (r)		goto out;#endif	r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);	if (r)		goto out;	r = read_fw_regs_offset(chip);	if (r)		goto out;	/* GPI is always disabled, also in the other driver.	 */	r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);	if (r)		goto out;	r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);	if (r)		goto out;	/* Currently we support IEEE 802.11g for full and high speed USB.	 * It might be discussed, whether we should suppport pure b mode for	 * full speed USB.	 */	r = set_mandatory_rates(chip, IEEE80211G);	if (r)		goto out;	/* Disabling interrupts is certainly a smart thing here.	 */	r = disable_hwint(chip);	if (r)		goto out;	r = read_pod(chip, &rf_type);	if (r)		goto out;	r = hw_init(chip);	if (r)		goto out;	r = zd_rf_init_hw(&chip->rf, rf_type);	if (r)		goto out;	r = print_fw_version(chip);	if (r)		goto out;#ifdef DEBUG	dump_fw_registers(chip);	r = test_init(chip);	if (r)		goto out;#endif /* DEBUG */	r = read_cal_int_tables(chip);	if (r)		goto out;	print_id(chip);out:	mutex_unlock(&chip->mutex);	return r;}static int update_pwr_int(struct zd_chip *chip, u8 channel){	u8 value = chip->pwr_int_values[channel - 1];	return zd_iowrite16_locked(chip, value, CR31);}static int update_pwr_cal(struct zd_chip *chip, u8 channel){	u8 value = chip->pwr_cal_values[channel-1];	return zd_iowrite16_locked(chip, value, CR68);}static int update_ofdm_cal(struct zd_chip *chip, u8 channel){	struct zd_ioreq16 ioreqs[3];	ioreqs[0].addr = CR67;	ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];	ioreqs[1].addr = CR66;	ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];	ioreqs[2].addr = CR65;	ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));}static int update_channel_integration_and_calibration(struct zd_chip *chip,	                                              u8 channel){	int r;	if (!zd_rf_should_update_pwr_int(&chip->rf))		return 0;	r = update_pwr_int(chip, channel);	if (r)		return r;	if (zd_chip_is_zd1211b(chip)) {		static const struct zd_ioreq16 ioreqs[] = {			{ CR69, 0x28 },			{},			{ CR69, 0x2a },		};		r = update_ofdm_cal(chip, channel);		if (r)			return r;		r = update_pwr_cal(chip, channel);		if (r)			return r;		r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));		if (r)			return r;	}	return 0;}/* The CCK baseband gain can be optionally patched by the EEPROM */static int patch_cck_gain(struct zd_chip *chip){	int r;	u32 value;	if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))		return 0;	ZD_ASSERT(mutex_is_locked(&chip->mutex));	r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);	if (r)		return r;	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);	return zd_iowrite16_locked(chip, value & 0xff, CR47);}int zd_chip_set_channel(struct zd_chip *chip, u8 channel){	int r, t;	mutex_lock(&chip->mutex);	r = zd_chip_lock_phy_regs(chip);	if (r)		goto out;	r = zd_rf_set_channel(&chip->rf, channel);	if (r)		goto unlock;	r = update_channel_integration_and_calibration(chip, channel);	if (r)		goto unlock;	r = patch_cck_gain(chip);	if (r)		goto unlock;	r = patch_6m_band_edge(chip, channel);	if (r)		goto unlock;	r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);unlock:	t = zd_chip_unlock_phy_regs(chip);	if (t && !r)		r = t;out:	mutex_unlock(&chip->mutex);	return r;}u8 zd_chip_get_channel(struct zd_chip *chip){	u8 channel;	mutex_lock(&chip->mutex);	channel = chip->rf.channel;	mutex_unlock(&chip->mutex);	return channel;}int zd_chip_control_leds(struct zd_chip *chip, enum led_status status){	const zd_addr_t a[] = {		fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),		CR_LED,	};	int r;	u16 v[ARRAY_SIZE(a)];	struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {		[0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },		[1] = { CR_LED },	};	u16 other_led;	mutex_lock(&chip->mutex);	r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));	if (r)		goto out;	other_led = chip->link_led == LED1 ? LED2 : LED1;	switch (status) {	case LED_OFF:		ioreqs[0].value = FW_LINK_OFF;		ioreqs[1].value = v[1] & ~(LED1|LED2);		break;	case LED_SCANNING:		ioreqs[0].value = FW_LINK_OFF;		ioreqs[1].value = v[1] & ~other_led;		if (get_seconds() % 3 == 0) {			ioreqs[1].value &= ~chip->link_led;		} else {			ioreqs[1].value |= chip->link_led;		}		break;	case LED_ASSOCIATED:		ioreqs[0].value = FW_LINK_TX;		ioreqs[1].value = v[1] & ~other_led;		ioreqs[1].value |= chip->link_led;		break;	default:		r = -EINVAL;		goto out;	}	if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {		r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));		if (r)			goto out;	}	r = 0;out:	mutex_unlock(&chip->mutex);	return r;}int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates){	ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);	dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);	return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);}static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size){	static const u16 constants[] = {		715, 655, 585, 540, 470, 410, 360, 315,		270, 235, 205, 175, 150, 125, 105,  85,		 65,  50,  40,  25,  15	};	int i;	u32 x;	/* It seems that their quality parameter is somehow per signal	 * and is now transferred per bit.	 */	switch (zd_rate) {	case ZD_OFDM_RATE_6M:	case ZD_OFDM_RATE_12M:	case ZD_OFDM_RATE_24M:		size *= 2;		break;	case ZD_OFDM_RATE_9M:	case ZD_OFDM_RATE_18M:	case ZD_OFDM_RATE_36M:	case ZD_OFDM_RATE_54M:		size *= 4;		size /= 3;		break;	case ZD_OFDM_RATE_48M:		size *= 3;		size /= 2;		break;	default:		return -EINVAL;	}	x = (10000 * status_quality)/size;	for (i = 0; i < ARRAY_SIZE(constants); i++) {		if (x > constants[i])			break;	}	switch (zd_rate) {	case ZD_OFDM_RATE_6M:	case ZD_OFDM_RATE_9M:		i += 3;		break;	case ZD_OFDM_RATE_12M:	case ZD_OFDM_RATE_18M:		i += 5;		break;	case ZD_OFDM_RATE_24M:	case ZD_OFDM_RATE_36M:		i += 9;		break;	case ZD_OFDM_RATE_48M:	case ZD_OFDM_RATE_54M:		i += 15;		break;	default:		return -EINVAL;	}	return i;}static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size){	int r;	r = ofdm_qual_db(status_quality, zd_rate, size);	ZD_ASSERT(r >= 0);	if (r < 0)		r = 0;	r = (r * 100)/29;	return r <= 100 ? r : 100;}static unsigned int log10times100(unsigned int x){	static const u8 log10[] = {		  0,		  0,   30,   47,   60,   69,   77,   84,   90,   95,  100,		104,  107,  111,  114,  117,  120,  123,  125,  127,  130,		132,  134,  136,  138,  139,  141,  143,  144,  146,  147,		149,  150,  151,  153,  154,  155,  156,  157,  159,  160,		161,  162,  163,  164,  165,  166,  167,  168,  169,  169,		170,  171,  172,  173,  174,  174,  175,  176,  177,  177,		178,  179,  179,  180,  181,  181,  182,  183,  183,  184,		185,  185,  186,  186,  187,  188,  188,  189,  189,  190,		190,  191,  191,  192,  192,  193,  193,  194,  194,  195,		195,  196,  196,  197,  197,  198,  198,  199,  199,  200,		200,  200,  201,  201,  202,  202,  202,  203,  203,  204,		204,  204,  205,  205,  206,  206,  206,  207,  207,  207,		208,  208,  208,  209,  209,  210,  210,  210,  211,  211,		211,  212,  212,  212,  213,  213,  213,  213,  214,  214,		214,  215,  215,  215,  216,  216,  216,  217,  217,  217,		217,  218,  218,  218,  219,  219,  219,  219,  220,  220,		220,  220,  221,  221,  221,  222,  222,  222,  222,  223,		223,  223,  223,  224,  224,  224,  224,	};	return x < ARRAY_SIZE(log10) ? log10[x] : 225;}enum {	MAX_CCK_EVM_DB = 45,};static int cck_evm_db(u8 status_quality){	return (20 * log10times100(status_quality)) / 100;}static int cck_snr_db(u8 status_quality){	int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);	ZD_ASSERT(r >= 0);	return r;}static int cck_qual_percent(u8 status_quality){	int r;	r = cck_snr_db(status_quality);	r = (100*r)/17;	return r <= 100 ? r : 100;}static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame){	return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame);}u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,	              const struct rx_status *status){	return (status->frame_status&ZD_RX_OFDM) ?		ofdm_qual_percent(status->signal_quality_ofdm,					  zd_rate_from_ofdm_plcp_header(rx_frame),			          size) :		cck_qual_percent(status->signal_quality_cck);}u8 zd_rx_strength_percent(u8 rssi){	int r = (rssi*100) / 41;	if (r > 100)		r = 100;	return (u8) r;}u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status){	static const u16 ofdm_rates[] = {		[ZD_OFDM_PLCP_RATE_6M]  = 60,		[ZD_OFDM_PLCP_RATE_9M]  = 90,		[ZD_OFDM_PLCP_RATE_12M] = 120,		[ZD_OFDM_PLCP_RATE_18M] = 180,		[ZD_OFDM_PLCP_RATE_24M] = 240,		[ZD_OFDM_PLCP_RATE_36M] = 360,		[ZD_OFDM_PLCP_RATE_48M] = 480,		[ZD_OFDM_PLCP_RATE_54M] = 540,	};	u16 rate;	if (status->frame_status & ZD_RX_OFDM) {		/* Deals with PLCP OFDM rate (not zd_rates) */		u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);		rate = ofdm_rates[ofdm_rate & 0xf];	} else {		switch (zd_cck_plcp_header_signal(rx_frame)) {		case ZD_CCK_PLCP_SIGNAL_1M:			rate = 10;			break;		case ZD_CCK_PLCP_SIGNAL_2M:			rate = 20;			break;		case ZD_CCK_PLCP_SIGNAL_5M5:			rate = 55;			break;		case ZD_CCK_PLCP_SIGNAL_11M:			rate = 110;			break;		default:			rate = 0;		}	}	return rate;}int zd_chip_switch_radio_on(struct zd_chip *chip){	int r;	mutex_lock(&chip->mutex);	r = zd_switch_radio_on(&chip->rf);	mutex_unlock(&chip->mutex);	return r;}int zd_chip_switch_radio_off(struct zd_chip *chip){	int r;	mutex_lock(&chip->mutex);	r = zd_switch_radio_off(&chip->rf);	mutex_unlock(&chip->mutex);	return r;}int zd_chip_enable_int(struct zd_chip *chip){	int r;	mutex_lock(&chip->mutex);	r = zd_usb_enable_int(&chip->usb);	mutex_unlock(&chip->mutex);	return r;}void zd_chip_disable_int(struct zd_chip *chip){	mutex_lock(&chip->mutex);	zd_usb_disable_int(&chip->usb);	mutex_unlock(&chip->mutex);}int zd_chip_enable_rx(struct zd_chip *chip){	int r;	mutex_lock(&chip->mutex);	r = zd_usb_enable_rx(&chip->usb);	mutex_unlock(&chip->mutex);	return r;}void zd_chip_disable_rx(struct zd_chip *chip){	mutex_lock(&chip->mutex);	zd_usb_disable_rx(&chip->usb);	mutex_unlock(&chip->mutex);}int zd_rfwritev_locked(struct zd_chip *chip,	               const u32* values, unsigned int count, u8 bits){	int r;	unsigned int i;	for (i = 0; i < count; i++) {		r = zd_rfwrite_locked(chip, values[i], bits);		if (r)			return r;	}	return 0;}/* * We can optionally program the RF directly through CR regs, if supported by * the hardware. This is much faster than the older method. */int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value){	struct zd_ioreq16 ioreqs[] = {		{ CR244, (value >> 16) & 0xff },		{ CR243, (value >>  8) & 0xff },		{ CR242,  value        & 0xff },	};	ZD_ASSERT(mutex_is_locked(&chip->mutex));	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));}int zd_rfwritev_cr_locked(struct zd_chip *chip,	                  const u32 *values, unsigned int count){	int r;	unsigned int i;	for (i = 0; i < count; i++) {		r = zd_rfwrite_cr_locked(chip, values[i]);		if (r)			return r;	}	return 0;}int zd_chip_set_multicast_hash(struct zd_chip *chip,	                       struct zd_mc_hash *hash){	struct zd_ioreq32 ioreqs[] = {		{ CR_GROUP_HASH_P1, hash->low },		{ CR_GROUP_HASH_P2, hash->high },	};	return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -