int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm) { u32 val, hash_lo, hash_hi; struct adapter *adap = mac->adapter; unsigned int oft = mac->offset; val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES; if (rm->dev->flags & IFF_PROMISC) val |= F_COPYALLFRAMES; t3_write_reg(adap, A_XGM_RX_CFG + oft, val); if (rm->dev->flags & IFF_ALLMULTI) hash_lo = hash_hi = 0xffffffff; else { u8 *addr; int exact_addr_idx = mac->nucast; hash_lo = hash_hi = 0; while ((addr = t3_get_next_mcaddr(rm))) if (exact_addr_idx < EXACT_ADDR_FILTERS) set_addr_filter(mac, exact_addr_idx++, addr); else { int hash = hash_hw_addr(addr); if (hash < 32) hash_lo |= (1 << hash); else hash_hi |= (1 << (hash - 32)); } } t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, hash_lo); t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, hash_hi); return 0; }
/* Set one of the station's unicast MAC addresses. */ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]) { if (idx >= mac->nucast) return -EINVAL; set_addr_filter(mac, idx, addr); return 0; }
/** * t3_mac_set_address - set one of the station's unicast MAC addresses * @mac: the MAC handle * @idx: index of the exact address match filter to use * @addr: the Ethernet address * * Set one of the station's unicast MAC addresses. */ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]) { if (mac->multiport) idx = mac->ext_port + idx * mac->adapter->params.nports; if (idx >= mac->nucast) return -EINVAL; set_addr_filter(mac, idx, addr); if (mac->multiport && idx < mac->adapter->params.nports) t3_vsc7323_set_addr(mac->adapter, addr, idx); return 0; }
/** * t3_mac_set_rx_mode - set the Rx mode and address filters * @mac: the MAC to configure * @rm: structure containing the Rx mode and MAC addresses needed * * Configures the MAC Rx mode (promiscuity, etc) and exact and hash * address filters. */ int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm) { u32 hash_lo, hash_hi; adapter_t *adap = mac->adapter; unsigned int oft = mac->offset; if (promisc_rx_mode(rm)) mac->promisc_map |= 1 << mac->ext_port; else mac->promisc_map &= ~(1 << mac->ext_port); t3_set_reg_field(adap, A_XGM_RX_CFG + oft, F_COPYALLFRAMES, mac->promisc_map ? F_COPYALLFRAMES : 0); if (allmulti_rx_mode(rm) || mac->multiport) hash_lo = hash_hi = 0xffffffff; else { u8 *addr; int exact_addr_idx = mac->nucast; hash_lo = hash_hi = 0; while ((addr = t3_get_next_mcaddr(rm))) if (exact_addr_idx < EXACT_ADDR_FILTERS) set_addr_filter(mac, exact_addr_idx++, addr); else { int hash = hash_hw_addr(addr); if (hash < 32) hash_lo |= (1 << hash); else hash_hi |= (1 << (hash - 32)); } } t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, hash_lo); t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, hash_hi); return 0; }
int t3_mac_set_rx_mode(struct cmac *mac, struct net_device *dev) { u32 val, hash_lo, hash_hi; struct adapter *adap = mac->adapter; unsigned int oft = mac->offset; val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES; if (dev->flags & IFF_PROMISC) val |= F_COPYALLFRAMES; t3_write_reg(adap, A_XGM_RX_CFG + oft, val); if (dev->flags & IFF_ALLMULTI) hash_lo = hash_hi = 0xffffffff; else { struct netdev_hw_addr *ha; int exact_addr_idx = mac->nucast; hash_lo = hash_hi = 0; netdev_for_each_mc_addr(ha, dev) if (exact_addr_idx < EXACT_ADDR_FILTERS) set_addr_filter(mac, exact_addr_idx++, ha->addr); else { int hash = hash_hw_addr(ha->addr); if (hash < 32) hash_lo |= (1 << hash); else hash_hi |= (1 << (hash - 32)); } } t3_write_reg(adap, A_XGM_RX_HASH_LOW + oft, hash_lo); t3_write_reg(adap, A_XGM_RX_HASH_HIGH + oft, hash_hi); return 0; }