int acx100_read_config(struct acx_softc *sc, struct acx_config *conf) { struct acx100_conf_cca_mode cca; struct acx100_conf_ed_thresh ed; struct ifnet *ifp = &sc->sc_ic.ic_if; /* * NOTE: * CCA mode and ED threshold MUST be read during initialization * or the acx100 card won't work as expected */ /* Get CCA mode */ if (acx_get_conf(sc, ACX_CONF_CCA_MODE, &cca, sizeof(cca)) != 0) { printf("%s: %s can't get cca mode\n", ifp->if_xname, __func__); return (ENXIO); } conf->cca_mode = cca.cca_mode; DPRINTF(("%s: cca mode %02x\n", ifp->if_xname, cca.cca_mode)); /* Get ED threshold */ if (acx_get_conf(sc, ACX_CONF_ED_THRESH, &ed, sizeof(ed)) != 0) { printf("%s: %s can't get ed threshold\n", ifp->if_xname, __func__); return (ENXIO); } conf->ed_thresh = ed.ed_thresh; DPRINTF(("%s: ed threshold %02x\n", ifp->if_xname, ed.ed_thresh)); return (0); }
int acx100_init_tmplt(struct acx_softc *sc) { struct acx_conf_mmap mem_map; struct ifnet *ifp = &sc->sc_ic.ic_if; /* Set templates start address */ if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't get mmap\n", ifp->if_xname); return (1); } mem_map.pkt_tmplt_start = mem_map.wep_cache_end; if (acx_set_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't set mmap\n", ifp->if_xname); return (1); } /* Initialize various packet templates */ if (acx_init_tmplt_ordered(sc) != 0) { printf("%s: can't init tmplt\n", ifp->if_xname); return (1); } return (0); }
int acx100_init_wep(struct acx_softc *sc) { struct acx_conf_wepopt wep_opt; struct acx_conf_mmap mem_map; struct ifnet *ifp = &sc->sc_ic.ic_if; /* Set WEP cache start/end address */ if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't get mmap\n", ifp->if_xname); return (1); } mem_map.wep_cache_start = htole32(letoh32(mem_map.code_end) + 4); mem_map.wep_cache_end = htole32(letoh32(mem_map.code_end) + 4); if (acx_set_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't set mmap\n", ifp->if_xname); return (1); } /* Set WEP options */ wep_opt.nkey = htole16(IEEE80211_WEP_NKID + 10); wep_opt.opt = WEPOPT_HDWEP; if (acx_set_conf(sc, ACX_CONF_WEPOPT, &wep_opt, sizeof(wep_opt)) != 0) { printf("%s: can't set wep opt\n", ifp->if_xname); return (1); } return (0); }
int acx100_init_fw_ring(struct acx_softc *sc) { struct acx100_conf_fw_ring ring; struct acx_conf_mmap mem_map; struct ifnet *ifp = &sc->sc_ic.ic_if; uint32_t txring_start, rxring_start, ring_end; /* Set firmware descriptor ring start address */ if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't get mmap\n", ifp->if_xname); return (1); } txring_start = letoh32(mem_map.pkt_tmplt_end) + 4; rxring_start = txring_start + ACX100_FW_TXRING_SIZE; ring_end = rxring_start + ACX100_FW_RXRING_SIZE; mem_map.fw_desc_start = htole32(txring_start); if (acx_set_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't set mmap\n", ifp->if_xname); return (1); } /* Set firmware descriptor ring configure */ bzero(&ring, sizeof(ring)); ring.fw_ring_size = htole32(ACX100_FW_TXRING_SIZE + ACX100_FW_RXRING_SIZE + 8); ring.fw_txring_num = 1; ring.fw_txring_addr = htole32(txring_start); ring.fw_txring_prio = ACX100_TXRING_PRIO_DEFAULT; ring.fw_txdesc_num = 0; /* XXX ignored?? */ ring.fw_rxring_addr = htole32(rxring_start); ring.fw_rxdesc_num = 0; /* XXX ignored?? */ ring.opt = ACX100_RINGOPT_AUTO_RESET; ACX100_SET_RING_END(&ring, ring_end); if (acx_set_conf(sc, ACX100_CONF_FW_RING, &ring, sizeof(ring)) != 0) { printf("%s: can't set fw ring configure\n", ifp->if_xname); return (1); } /* Setup firmware TX/RX descriptor ring */ acx100_init_fw_txring(sc, txring_start); acx100_init_fw_rxring(sc, rxring_start); return (0); }
int acx111_init_memory(struct acx_softc *sc) { struct acx111_conf_mem mem; struct acx111_conf_meminfo mem_info; struct ifnet *ifp = &sc->sc_ic.ic_if; /* Set memory configuration */ bzero(&mem, sizeof(mem)); mem.sta_max = htole16(ACX111_STA_MAX); mem.memblk_size = htole16(ACX_MEMBLOCK_SIZE); mem.rx_memblk_perc = ACX111_RX_MEMBLK_PERCENT; mem.opt = ACX111_MEMOPT_DEFAULT; mem.xfer_perc = ACX111_XFER_PERCENT; mem.fw_rxring_num = 1; mem.fw_rxring_type = ACX111_RXRING_TYPE_DEFAULT; mem.fw_rxring_prio = ACX111_RXRING_PRIO_DEFAULT; mem.fw_rxdesc_num = ACX_RX_DESC_CNT; mem.h_rxring_paddr = htole32(sc->sc_ring_data.rx_ring_paddr); mem.fw_txring_num = 1; mem.fw_txring_attr = ACX111_TXRING_ATTR_DEFAULT; mem.fw_txdesc_num = ACX_TX_DESC_CNT; if (acx_set_conf(sc, ACX111_CONF_MEM, &mem, sizeof(mem)) != 0) { printf("%s: can't set mem\n", ifp->if_xname); return (1); } /* Get memory configuration */ if (acx_get_conf(sc, ACX111_CONF_MEMINFO, &mem_info, sizeof(mem_info)) != 0) { printf("%s: can't get meminfo\n", ifp->if_xname); return (1); } /* Setup firmware TX descriptor ring */ acx111_init_fw_txring(sc, letoh32(mem_info.fw_txring_start)); /* * There is no need to setup firmware RX descriptor ring, * it is automaticly setup by hardware. */ return (0); }
int acx111_write_config(struct acx_softc *sc, struct acx_config *conf) { struct acx111_conf_txpower tx_power; struct acx111_conf_option opt; struct ifnet *ifp = &sc->sc_ic.ic_if; uint32_t dataflow; /* Set TX power */ tx_power.txpower = ACX111_TXPOWER_VAL; if (acx_set_conf(sc, ACX_CONF_TXPOWER, &tx_power, sizeof(tx_power)) != 0) { printf("%s: %s can't set TX power\n", ifp->if_xname, __func__); return (ENXIO); } /* * Turn off hardware WEP */ if (acx_get_conf(sc, ACX_CONF_OPTION, &opt, sizeof(opt)) != 0) { printf("%s: %s can't get option\n", ifp->if_xname, __func__); return (ENXIO); } dataflow = letoh32(opt.dataflow) | ACX111_DF_NO_TXENCRYPT | ACX111_DF_NO_RXDECRYPT; opt.dataflow = htole32(dataflow); if (acx_set_conf(sc, ACX_CONF_OPTION, &opt, sizeof(opt)) != 0) { printf("%s: %s can't set option\n", ifp->if_xname, __func__); return (ENXIO); } return (0); }
int acx100_init_memory(struct acx_softc *sc) { struct acx100_conf_memblk_size memblk_sz; struct acx100_conf_mem mem; struct acx_conf_mmap mem_map; struct ifnet *ifp = &sc->sc_ic.ic_if; uint32_t memblk_start, memblk_end; int total_memblk, txblk_num, rxblk_num; /* Set memory block start address */ if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't get mmap\n", ifp->if_xname); return (1); } mem_map.memblk_start = htole32(MEMBLK_ALIGN(letoh32(mem_map.fw_desc_end) + 4)); if (acx_set_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't set mmap\n", ifp->if_xname); return (1); } /* Set memory block size */ memblk_sz.memblk_size = htole16(ACX_MEMBLOCK_SIZE); if (acx_set_conf(sc, ACX_CONF_MEMBLK_SIZE, &memblk_sz, sizeof(memblk_sz)) != 0) { printf("%s: can't set mem block size\n", ifp->if_xname); return (1); } /* Get memory map after setting it */ if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) { printf("%s: can't get mmap again\n", ifp->if_xname); return (1); } memblk_start = letoh32(mem_map.memblk_start); memblk_end = letoh32(mem_map.memblk_end); /* Set memory options */ mem.opt = htole32(ACX100_MEMOPT_MEMBLOCK | ACX100_MEMOPT_HOSTDESC); mem.h_rxring_paddr = htole32(sc->sc_ring_data.rx_ring_paddr); total_memblk = (memblk_end - memblk_start) / ACX_MEMBLOCK_SIZE; rxblk_num = total_memblk / 2; /* 50% */ txblk_num = total_memblk - rxblk_num; /* 50% */ DPRINTF(("%s: \ttotal memory blocks\t%d\n" "\trx memory blocks\t%d\n" "\ttx memory blocks\t%d\n", ifp->if_xname, total_memblk, rxblk_num, txblk_num)); mem.rx_memblk_num = htole16(rxblk_num); mem.tx_memblk_num = htole16(txblk_num); mem.rx_memblk_addr = htole32(MEMBLK_ALIGN(memblk_start)); mem.tx_memblk_addr = htole32(MEMBLK_ALIGN(memblk_start + (ACX_MEMBLOCK_SIZE * rxblk_num))); if (acx_set_conf(sc, ACX100_CONF_MEMOPT, &mem, sizeof(mem)) != 0) { printf("%s: can't set mem options\n", ifp->if_xname); return (1); } /* Initialize memory */ if (acx_exec_command(sc, ACXCMD_INIT_MEM, NULL, 0, NULL, 0) != 0) { printf("%s: can't init mem\n", ifp->if_xname); return (1); } return (0); }