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

📄 zd_chip.c

📁 zd1211无线网卡驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	u8 rf_type;	dev_dbg_f(zd_chip_dev(chip), "\n");	mutex_lock(&chip->mutex);	chip->is_zd1211b = (device_type == DEVICE_ZD1211B) != 0;#ifdef DEBUG	r = test_init(chip);	if (r)		goto out;#endif	r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);	if (r)		goto out;	r = zd_usb_init_hw(&chip->usb);	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_e2p_mac_addr(chip);	if (r)		goto out;	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];	dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",		 channel, value);	return zd_iowrite32_locked(chip, value, CR31);}static int update_pwr_cal(struct zd_chip *chip, u8 channel){	u8 value = chip->pwr_cal_values[channel-1];	dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",		 channel, value);	return zd_iowrite32_locked(chip, value, CR68);}static int update_ofdm_cal(struct zd_chip *chip, u8 channel){	struct zd_ioreq32 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];	dev_dbg_f(zd_chip_dev(chip),		"channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",		channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);	return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));}static int update_channel_integration_and_calibration(struct zd_chip *chip,	                                              u8 channel){	int r;	r = update_pwr_int(chip, channel);	if (r)		return r;	if (chip->is_zd1211b) {		static const struct zd_ioreq32 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_iowrite32a_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)		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_iowrite32_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;}static u16 led_mask(int led){	switch (led) {	case 1:		return LED1;	case 2:		return LED2;	default:		return 0;	}}static int read_led_reg(struct zd_chip *chip, u16 *status){	ZD_ASSERT(mutex_is_locked(&chip->mutex));	return zd_ioread16_locked(chip, status, CR_LED);}static int write_led_reg(struct zd_chip *chip, u16 status){	ZD_ASSERT(mutex_is_locked(&chip->mutex));	return zd_iowrite16_locked(chip, status, CR_LED);}int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status){	int r, ret;	u16 mask = led_mask(led);	u16 reg;	if (!mask)		return -EINVAL;	mutex_lock(&chip->mutex);	r = read_led_reg(chip, &reg);	if (r)		return r;	switch (status) {	case LED_STATUS:		return (reg & mask) ? LED_ON : LED_OFF;	case LED_OFF:		reg &= ~mask;		ret = LED_OFF;		break;	case LED_FLIP:		reg ^= mask;		ret = (reg&mask) ? LED_ON : LED_OFF;		break;	case LED_ON:		reg |= mask;		ret = LED_ON;		break;	default:		return -EINVAL;	}	r = write_led_reg(chip, reg);	if (r) {		ret = r;		goto out;	}out:	mutex_unlock(&chip->mutex);	return r;}int zd_chip_led_flip(struct zd_chip *chip, int led,	const unsigned int *phases_msecs, unsigned int count){	int i, r;	enum led_status status;	r = zd_chip_led_status(chip, led, LED_STATUS);	if (r)		return r;	status = r;	for (i = 0; i < count; i++) {		r = zd_chip_led_status(chip, led, LED_FLIP);		if (r < 0)			goto out;		msleep(phases_msecs[i]);	}out:	zd_chip_led_status(chip, led, status);	return r;}int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates){	int r;	if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))		return -EINVAL;	mutex_lock(&chip->mutex);	r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);	mutex_unlock(&chip->mutex);	return r;}static int ofdm_qual_db(u8 status_quality, u8 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 (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 (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 rate, unsigned int size){	int r;	r = ofdm_qual_db(status_quality, 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;}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_ofdm_plcp_header_rate(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_RATE_6M]  = 60,		[ZD_OFDM_RATE_9M]  = 90,		[ZD_OFDM_RATE_12M] = 120,		[ZD_OFDM_RATE_18M] = 180,		[ZD_OFDM_RATE_24M] = 240,		[ZD_OFDM_RATE_36M] = 360,		[ZD_OFDM_RATE_48M] = 480,		[ZD_OFDM_RATE_54M] = 540,	};	u16 rate;	if (status->frame_status & ZD_RX_OFDM) {		u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);		rate = ofdm_rates[ofdm_rate & 0xf];	} else {		u8 cck_rate = zd_cck_plcp_header_rate(rx_frame);		switch (cck_rate) {		case ZD_CCK_SIGNAL_1M:			rate = 10;			break;		case ZD_CCK_SIGNAL_2M:			rate = 20;			break;		case ZD_CCK_SIGNAL_5M5:			rate = 55;			break;		case ZD_CCK_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;}

⌨️ 快捷键说明

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