📄 zd_chip.c
字号:
return r;}int zd_chip_unlock_phy_regs(struct zd_chip *chip){ int r; u32 tmp; ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = zd_ioread32_locked(chip, &tmp, CR_REG1); if (r) { dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r); return r; } dev_dbg_f(zd_chip_dev(chip), "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp | UNLOCK_PHY_REGS); tmp |= UNLOCK_PHY_REGS; r = zd_iowrite32_locked(chip, tmp, CR_REG1); if (r) dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r); return r;}/* CR157 can be optionally patched by the EEPROM */static int patch_cr157(struct zd_chip *chip){ int r; u32 value; if (!chip->patch_cr157) return 0; 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 >> 8); return zd_iowrite32_locked(chip, value >> 8, CR157);}/* * 6M band edge can be optionally overwritten for certain RF's * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge * bit (for AL2230, AL2230S) */static int patch_6m_band_edge(struct zd_chip *chip, int channel){ struct zd_ioreq16 ioreqs[] = { { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, { CR47, 0x1e }, }; if (!chip->patch_6m_band_edge || !chip->rf.patch_6m_band_edge) return 0; /* FIXME: Channel 11 is not the edge for all regulatory domains. */ if (channel == 1 || channel == 11) ioreqs[0].value = 0x12; dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel); return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));}static int zd1211_hw_reset_phy(struct zd_chip *chip){ static const struct zd_ioreq16 ioreqs[] = { { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 }, { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 }, { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f }, { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a }, { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c }, { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 }, { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b }, { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff }, { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 }, { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 }, { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 }, { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 }, { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 }, { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff }, { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 }, { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 }, { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 }, { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a }, { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 }, { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e }, { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, { }, { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 }, { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 }, { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 }, { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 }, { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C }, { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 }, { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 }, { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 }, { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f }, { CR123, 0x27 }, { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C }, { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 }, { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 }, { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 }, { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe }, { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, { CR170, 0xba }, { CR171, 0xba }, /* Note: CR204 must lead the CR203 */ { CR204, 0x7d }, { }, { CR203, 0x30 }, }; int r, t; dev_dbg_f(zd_chip_dev(chip), "\n"); r = zd_chip_lock_phy_regs(chip); if (r) goto out; r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); if (r) goto unlock; r = patch_cr157(chip);unlock: t = zd_chip_unlock_phy_regs(chip); if (t && !r) r = t;out: return r;}static int zd1211b_hw_reset_phy(struct zd_chip *chip){ static const struct zd_ioreq16 ioreqs[] = { { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 }, { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 }, { CR10, 0x81 }, /* power control { { CR11, 1 << 6 }, */ { CR11, 0x00 }, { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a }, { CR19, 0x48 }, { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */ { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x49 }, /* jointly decoder, no ASIC */ { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff }, { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 }, { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 }, { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 }, { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 }, { CR94, 0x01 }, { CR95, 0x20 }, /* ZD1211B */ { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 }, { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 }, { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e }, { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 }, { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 }, { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c }, { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 }, { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */ { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */ { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe }, { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, { CR170, 0xba }, { CR171, 0xba }, /* Note: CR204 must lead the CR203 */ { CR204, 0x7d }, {}, { CR203, 0x30 }, }; int r, t; dev_dbg_f(zd_chip_dev(chip), "\n"); r = zd_chip_lock_phy_regs(chip); if (r) goto out; r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); if (r) goto unlock; r = patch_cr157(chip);unlock: t = zd_chip_unlock_phy_regs(chip); if (t && !r) r = t;out: return r;}static int hw_reset_phy(struct zd_chip *chip){ return chip->is_zd1211b ? zd1211b_hw_reset_phy(chip) : zd1211_hw_reset_phy(chip);}static int zd1211_hw_init_hmac(struct zd_chip *chip){ static const struct zd_ioreq32 ioreqs[] = { { CR_ACK_TIMEOUT_EXT, 0x20 }, { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_ZD1211_RETRY_MAX, 0x2 }, { CR_SNIFFER_ON, 0 }, { CR_RX_FILTER, STA_RX_FILTER }, { CR_GROUP_HASH_P1, 0x00 }, { CR_GROUP_HASH_P2, 0x80000000 }, { CR_REG1, 0xa4 }, { CR_ADDA_PWR_DWN, 0x7f }, { CR_BCN_PLCP_CFG, 0x00f00401 }, { CR_PHY_DELAY, 0x00 }, { CR_ACK_TIMEOUT_EXT, 0x80 }, { CR_ADDA_PWR_DWN, 0x00 }, { CR_ACK_TIME_80211, 0x100 }, { CR_IFS_VALUE, 0x547c032 }, { CR_RX_PE_DELAY, 0x70 }, { CR_PS_CTRL, 0x10000000 }, { CR_RTS_CTS_RATE, 0x02030203 }, { CR_RX_THRESHOLD, 0x000c0640 }, { CR_AFTER_PNP, 0x1 }, { CR_WEP_PROTECT, 0x114 }, }; int r; dev_dbg_f(zd_chip_dev(chip), "\n"); ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));#ifdef DEBUG if (r) { dev_err(zd_chip_dev(chip), "error in zd_iowrite32a_locked. Error number %d\n", r); }#endif /* DEBUG */ return r;}static int zd1211b_hw_init_hmac(struct zd_chip *chip){ static const struct zd_ioreq32 ioreqs[] = { { CR_ACK_TIMEOUT_EXT, 0x20 }, { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_ZD1211B_RETRY_MAX, 0x02020202 }, { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f }, { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f }, { CR_ZD1211B_TX_PWR_CTL2, 0x003f001f }, { CR_ZD1211B_TX_PWR_CTL1, 0x001f000f }, { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, { CR_ZD1211B_TXOP, 0x01800824 }, { CR_SNIFFER_ON, 0 }, { CR_RX_FILTER, STA_RX_FILTER }, { CR_GROUP_HASH_P1, 0x00 }, { CR_GROUP_HASH_P2, 0x80000000 }, { CR_REG1, 0xa4 }, { CR_ADDA_PWR_DWN, 0x7f }, { CR_BCN_PLCP_CFG, 0x00f00401 }, { CR_PHY_DELAY, 0x00 }, { CR_ACK_TIMEOUT_EXT, 0x80 }, { CR_ADDA_PWR_DWN, 0x00 }, { CR_ACK_TIME_80211, 0x100 }, { CR_IFS_VALUE, 0x547c032 }, { CR_RX_PE_DELAY, 0x70 }, { CR_PS_CTRL, 0x10000000 }, { CR_RTS_CTS_RATE, 0x02030203 }, { CR_RX_THRESHOLD, 0x000c0640 }, { CR_AFTER_PNP, 0x1 }, { CR_WEP_PROTECT, 0x114 }, }; int r; dev_dbg_f(zd_chip_dev(chip), "\n"); ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); if (r) { dev_dbg_f(zd_chip_dev(chip), "error in zd_iowrite32a_locked. Error number %d\n", r); } return r;}static int hw_init_hmac(struct zd_chip *chip){ return chip->is_zd1211b ? zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);}struct aw_pt_bi { u32 atim_wnd_period; u32 pre_tbtt; u32 beacon_interval;};static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s){ int r; static const zd_addr_t aw_pt_bi_addr[] = { CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL }; u32 values[3]; r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr, ARRAY_SIZE(aw_pt_bi_addr)); if (r) { memset(s, 0, sizeof(*s)); return r; } s->atim_wnd_period = values[0]; s->pre_tbtt = values[1]; s->beacon_interval = values[2]; dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt, s->beacon_interval); return 0;}static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s){ struct zd_ioreq32 reqs[3]; if (s->beacon_interval <= 5) s->beacon_interval = 5; if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval) s->pre_tbtt = s->beacon_interval - 1; if (s->atim_wnd_period >= s->pre_tbtt) s->atim_wnd_period = s->pre_tbtt - 1; reqs[0].addr = CR_ATIM_WND_PERIOD; reqs[0].value = s->atim_wnd_period; reqs[1].addr = CR_PRE_TBTT; reqs[1].value = s->pre_tbtt; reqs[2].addr = CR_BCN_INTERVAL; reqs[2].value = s->beacon_interval; dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt, s->beacon_interval); return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));}static int set_beacon_interval(struct zd_chip *chip, u32 interval){ int r; struct aw_pt_bi s; ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = get_aw_pt_bi(chip, &s); if (r) return r; s.beacon_interval = interval; return set_aw_pt_bi(chip, &s);}int zd_set_beacon_interval(struct zd_chip *chip, u32 interval){ int r; mutex_lock(&chip->mutex); r = set_beacon_interval(chip, interval); mutex_unlock(&chip->mutex); return r;}static int hw_init(struct zd_chip *chip){ int r; dev_dbg_f(zd_chip_dev(chip), "\n"); ZD_ASSERT(mutex_is_locked(&chip->mutex)); r = hw_reset_phy(chip); if (r) return r; r = hw_init_hmac(chip); if (r) return r; r = set_beacon_interval(chip, 100); if (r) return r; return 0;}#ifdef DEBUGstatic int dump_cr(struct zd_chip *chip, const zd_addr_t addr, const char *addr_string){ int r; u32 value; r = zd_ioread32_locked(chip, &value, addr); if (r) { dev_dbg_f(zd_chip_dev(chip), "error reading %s. Error number %d\n", addr_string, r); return r; } dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n", addr_string, (unsigned int)value); return 0;}static int test_init(struct zd_chip *chip){ int r; r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP"); if (r) return r; r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN"); if (r) return r; return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");}static void dump_fw_registers(struct zd_chip *chip){ static const zd_addr_t addr[4] = { FW_FIRMWARE_VER, FW_USB_SPEED, FW_FIX_TX_RATE, FW_LINK_STATUS }; int r; u16 values[4]; r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr, ARRAY_SIZE(addr)); if (r) { dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n", r); return; } dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]); dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]); dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]); dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);}#endif /* DEBUG */static int print_fw_version(struct zd_chip *chip){ int r; u16 version; r = zd_ioread16_locked(chip, &version, FW_FIRMWARE_VER); if (r) return r; dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version); return 0;}static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std){ u32 rates; ZD_ASSERT(mutex_is_locked(&chip->mutex)); /* This sets the mandatory rates, which only depend from the standard * that the device is supporting. Until further notice we should try * to support 802.11g also for full speed USB. */ switch (std) { case IEEE80211B: rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; break; case IEEE80211G: rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; break; default: return -EINVAL; } return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);}int zd_chip_enable_hwint(struct zd_chip *chip){ int r; mutex_lock(&chip->mutex); r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT); mutex_unlock(&chip->mutex); return r;}static int disable_hwint(struct zd_chip *chip){ return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);}int zd_chip_disable_hwint(struct zd_chip *chip){ int r; mutex_lock(&chip->mutex); r = disable_hwint(chip); mutex_unlock(&chip->mutex); return r;}int zd_chip_init_hw(struct zd_chip *chip, u8 device_type){ int r;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -