Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl2_fw.c +32 −10 Original line number Diff line number Diff line Loading @@ -221,7 +221,7 @@ static int __atl2_fw_wait_init(struct atl_hw *hw) atl2_shared_buffer_write(hw, link_control, link_control); atl2_shared_buffer_get(hw, mtu, mtu); mtu = ATL_MAX_MTU; mtu = ATL_MAX_MTU + ETH_FCS_LEN + ETH_HLEN; atl2_shared_buffer_write(hw, mtu, mtu); return atl2_shared_buffer_finish_ack(hw); Loading Loading @@ -308,11 +308,11 @@ static void atl2_set_eee(struct atl_link_state *lstate, return; } link_options->eee_100M = eee_advertized & BIT(atl_link_type_idx_100m); link_options->eee_1G = eee_advertized & BIT(atl_link_type_idx_1g); link_options->eee_2P5G = eee_advertized & BIT(atl_link_type_idx_2p5g); link_options->eee_5G = eee_advertized & BIT(atl_link_type_idx_5g); link_options->eee_10G = eee_advertized & BIT(atl_link_type_idx_10g); link_options->eee_100M = !!(eee_advertized & BIT(atl_link_type_idx_100m)); link_options->eee_1G = !!(eee_advertized & BIT(atl_link_type_idx_1g)); link_options->eee_2P5G = !!(eee_advertized & BIT(atl_link_type_idx_2p5g)); link_options->eee_5G = !!(eee_advertized & BIT(atl_link_type_idx_5g)); link_options->eee_10G = !!(eee_advertized & BIT(atl_link_type_idx_10g)); } /* fw lock must be held */ Loading Loading @@ -387,6 +387,8 @@ static u32 a2_fw_caps_to_mask(struct device_link_caps_s *link_caps) supported |= BIT(atl_link_type_idx_2p5g) << ATL_EEE_BIT_OFFT; if (link_caps->eee_1G) supported |= BIT(atl_link_type_idx_1g) << ATL_EEE_BIT_OFFT; if (link_caps->eee_100M) supported |= BIT(atl_link_type_idx_100m) << ATL_EEE_BIT_OFFT; return supported; } Loading Loading @@ -422,6 +424,8 @@ static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps) rate |= BIT(atl_link_type_idx_2p5g) << ATL_EEE_BIT_OFFT; if (lkp_link_caps->eee_1G) rate |= BIT(atl_link_type_idx_1g) << ATL_EEE_BIT_OFFT; if (lkp_link_caps->eee_100M) rate |= BIT(atl_link_type_idx_100m) << ATL_EEE_BIT_OFFT; return rate; } Loading Loading @@ -679,10 +683,10 @@ static int atl2_fw_update_thermal(struct atl_hw *hw) atl_lock_fw(hw); atl2_shared_buffer_get(hw, thermal_shutdown, thermal_shutdown); thermal_shutdown.enable = enable; thermal_shutdown.shutdown_temperature = hw->thermal.crit; thermal_shutdown.warning_temperature = hw->thermal.high; thermal_shutdown.cold_temperature = hw->thermal.low; thermal_shutdown.shutdown_enable = enable; thermal_shutdown.shutdown_temp_threshold = hw->thermal.crit; thermal_shutdown.warning_hot_tempThreshold = hw->thermal.high; thermal_shutdown.warning_cold_temp_threshold = hw->thermal.low; atl2_shared_buffer_write(hw, thermal_shutdown, thermal_shutdown); ret = atl2_shared_buffer_finish_ack(hw); Loading @@ -696,6 +700,23 @@ static int atl2_fw_update_thermal(struct atl_hw *hw) return ret; } static int atl2_fw_set_pad_stripping(struct atl_hw *hw, bool on) { struct link_control_s link_control; int err = 0; atl_lock_fw(hw); atl2_shared_buffer_get(hw, link_control, link_control); link_control.enable_frame_padding_removal_rx = on; atl2_shared_buffer_write(hw, link_control, link_control); err = atl2_shared_buffer_finish_ack(hw); atl_unlock_fw(hw); return err; } static int atl2_fw_unsupported(struct atl_hw *hw) { return -ENOTSUPP; Loading Loading @@ -723,6 +744,7 @@ static struct atl_fw_ops atl2_fw_ops = { .get_phy_temperature = atl2_fw_get_phy_temperature, .set_mediadetect = (void *)atl2_fw_unsupported, .send_macsec_req = (void *)atl2_fw_unsupported, .set_pad_stripping = atl2_fw_set_pad_stripping, .get_mac_addr = atl2_fw_get_mac_addr, .__get_hbeat = __atl2_fw_get_hbeat, .set_phy_loopback = atl2_fw_set_phy_loopback, Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl2_fw.h +5 −6 Original line number Diff line number Diff line Loading @@ -66,14 +66,13 @@ struct link_control_s { }; struct thermal_shutdown_s { uint32_t enable:1; uint32_t shutdown_enable :1; uint32_t warning_enable :1; uint32_t rsvd:6; uint32_t cold_temperature:8; uint32_t warning_temperature:8; uint32_t shutdown_temperature:8; uint32_t shutdown_temp_threshold :8; uint32_t warning_cold_temp_threshold :8; uint32_t warning_hot_tempThreshold :8; }; struct mac_address_s { Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h +13 −10 Original line number Diff line number Diff line Loading @@ -18,10 +18,9 @@ #include <linux/netdevice.h> #include <linux/moduleparam.h> #define ATL_VERSION "1.1.0" #define ATL_VERSION "1.1.4" struct atl_nic; enum atl_fwd_notify; #include "atl_compat.h" #include "atl_hw.h" Loading Loading @@ -90,8 +89,8 @@ enum atl2_ntuple_cmd { ATL2_NTC_L3_IPV6_PROTO_SHIFT = 0x18, ATL2_NTC_L4_EN = BIT(0), /* Filter enabled */ ATL2_NTC_L4_SP = BIT(1), ATL2_NTC_L4_DP = BIT(2), ATL2_NTC_L4_DP = BIT(1), ATL2_NTC_L4_SP = BIT(2), }; struct atl2_rxf_l3 { Loading @@ -106,14 +105,14 @@ struct atl2_rxf_l3 { }; }; u16 proto; u16 cmd; u32 cmd; u16 usage; }; struct atl2_rxf_l4 { __be16 dst_port; __be16 src_port; u16 cmd; u32 cmd; u16 usage; }; Loading Loading @@ -210,7 +209,7 @@ struct atl_fwd { struct blocking_notifier_head nh_clients; }; #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) struct atl_fwdnl { struct atl_desc_ring ring_desc[ATL_NUM_FWD_RINGS * 2]; /* State of forced redirections */ Loading Loading @@ -241,10 +240,10 @@ struct atl_nic { spinlock_t stats_lock; struct work_struct work; #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) struct atl_fwd fwd; #endif #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) struct atl_fwdnl fwdnl; #endif Loading Loading @@ -383,12 +382,16 @@ int atl_update_eth_stats(struct atl_nic *nic); void atl_adjust_eth_stats(struct atl_ether_stats *stats, struct atl_ether_stats *base, bool add); void atl_fwd_release_rings(struct atl_nic *nic); #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) enum atl_fwd_notify; int atl_fwd_suspend_rings(struct atl_nic *nic); int atl_fwd_resume_rings(struct atl_nic *nic); void atl_fwd_notify(struct atl_nic *nic, enum atl_fwd_notify notif, void *data); #else static inline int atl_fwd_suspend_rings(struct atl_nic *nic) { return 0; } static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; } static inline void atl_fwd_notify(struct atl_nic *nic, enum atl_fwd_notify notif, void *data) {} #endif int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay); void atl_refresh_rxfs(struct atl_nic *nic); Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_ethtool.c +40 −49 Original line number Diff line number Diff line Loading @@ -190,9 +190,9 @@ static int atl_set_fixed_speed(struct atl_hw *hw, unsigned int speed, if (lstate->eee_enabled) { atl_link_to_kernel(lstate->supported >> ATL_EEE_BIT_OFFT, &tmp, true); &tmp, false); /* advertize the supported links */ tmp = atl_kernel_to_link(&tmp, true); tmp = atl_kernel_to_link(&tmp, false); lstate->advertized |= tmp << ATL_EEE_BIT_OFFT; } Loading Loading @@ -425,7 +425,7 @@ static int atl_set_pauseparam(struct net_device *ndev, struct atl_link_state *lstate = &hw->link_state; struct atl_fc_state *fc = &lstate->fc; if (atl_fw_major(hw) < 2) if ((hw->chip_id == ATL_ATLANTIC) && (atl_fw_major(hw) < 2)) return -EOPNOTSUPP; if (pause->autoneg) Loading Loading @@ -459,6 +459,7 @@ static int atl_get_eee(struct net_device *ndev, struct ethtool_eee *eee) eee->eee_enabled = eee->tx_lpi_enabled = lstate->eee_enabled; eee->eee_active = lstate->eee; if (lstate->link) ret = atl_get_lpi_timer(nic, &eee->tx_lpi_timer); return ret; Loading @@ -469,31 +470,28 @@ static int atl_set_eee(struct net_device *ndev, struct ethtool_eee *eee) struct atl_nic *nic = netdev_priv(ndev); struct atl_hw *hw = &nic->hw; struct atl_link_state *lstate = &hw->link_state; uint32_t tmp = 0; uint32_t lpi_timer = 0; unsigned long tmp = 0; if (atl_fw_major(hw) < 2) if ((hw->chip_id == ATL_ATLANTIC) && (atl_fw_major(hw) < 2)) return -EOPNOTSUPP; atl_get_lpi_timer(nic, &tmp); if (eee->tx_lpi_timer != tmp) atl_get_lpi_timer(nic, &lpi_timer); if (eee->tx_lpi_timer != lpi_timer) return -EOPNOTSUPP; lstate->eee_enabled = eee->eee_enabled; if (lstate->eee_enabled) { atl_link_to_kernel(lstate->supported >> ATL_EEE_BIT_OFFT, (unsigned long *)&tmp, true); &tmp, false); if (eee->advertised & ~tmp) return -EINVAL; /* advertize the requested link or all supported */ if (eee->advertised) tmp = atl_kernel_to_link( (unsigned long *)&eee->advertised, true); else tmp = atl_kernel_to_link( (unsigned long *)&tmp, true); tmp = eee->advertised; tmp = atl_kernel_to_link(&tmp, false); } lstate->advertized &= ~ATL_EEE_MASK; Loading Loading @@ -735,7 +733,7 @@ static int atl_get_sset_count(struct net_device *ndev, int sset) return ARRAY_SIZE(tx_stat_descs) * (nic->nvecs + 1) + ARRAY_SIZE(rx_stat_descs) * (nic->nvecs + 1) + ARRAY_SIZE(eth_stat_descs) #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) + ARRAY_SIZE(tx_stat_descs) * hweight_long(nic->fwd.ring_map[ATL_FWDIR_TX]) + ARRAY_SIZE(rx_stat_descs) * Loading Loading @@ -800,7 +798,7 @@ static void atl_get_strings(struct net_device *ndev, uint32_t sset, atl_copy_stats_string_set(&p, prefix); } #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) for (i = 0; i < ATL_NUM_FWD_RINGS; i++) { snprintf(prefix, sizeof(prefix), "fwd_ring_%d_", i); Loading Loading @@ -908,7 +906,7 @@ static void atl_get_ethtool_stats(struct net_device *ndev, atl_write_stats(&tmp.rx, rx_stat_descs, data, uint64_t); } #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) for (i = 0; i < ATL_NUM_FWD_RINGS; i++) { struct atl_ring_stats tmp; Loading Loading @@ -1045,27 +1043,10 @@ static int atl_set_pad_stripping(struct atl_nic *nic, bool on) { struct atl_hw *hw = &nic->hw; int ret; uint32_t msm_opts; if (hw->mcp.fw_rev < 0x0300008e) return -EOPNOTSUPP; ret = atl_read_fwsettings_word(hw, atl_fw2_setings_msm_opts, &msm_opts); if (ret) return ret; ret = hw->mcp.ops->set_pad_stripping(hw, on); msm_opts &= ~atl_fw2_settings_msm_opts_strip_pad; msm_opts |= !!on << atl_fw2_settings_msm_opts_strip_pad_shift; ret = atl_write_fwsettings_word(hw, atl_fw2_setings_msm_opts, msm_opts); if (ret) return ret; /* Restart aneg to make FW apply the new settings */ hw->mcp.ops->restart_aneg(hw); return 0; } int atl_set_media_detect(struct atl_nic *nic, bool on) Loading Loading @@ -1408,7 +1389,7 @@ static int atl_rxf_check_ring(struct atl_nic *nic, uint32_t ring) if (ring < nic->nvecs || ring == ATL_RXF_RING_ANY) return 0; #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) if (test_bit(ring, &nic->fwd.ring_map[ATL_FWDIR_RX])) return 0; #endif Loading Loading @@ -1791,8 +1772,8 @@ static void atl2_rxf_set_ntuple(struct atl_nic *nic, if (ntuple->cmd[idx] & ATL_NTC_PROTO) l3.cmd |= ntuple->cmd[idx] & ATL_NTC_V6 ? ATL2_NTC_L3_IPV6_PROTO : ATL2_NTC_L3_IPV4_PROTO; ATL2_NTC_L3_IPV6_PROTO | ATL2_NTC_L3_IPV6_EN : ATL2_NTC_L3_IPV4_PROTO | ATL2_NTC_L3_IPV4_EN; switch (ntuple->cmd[idx] & ATL_NTC_L4_MASK) { case ATL_NTC_L4_TCP: Loading Loading @@ -2220,9 +2201,9 @@ static void atl2_update_ntuple_flt(struct atl_nic *nic, int idx) mask |= ATL2_RPF_TAG_L3_V6_MASK; cmd |= (l3_idx + 1) << 0x14; if (l3->cmd & ATL2_NTC_L3_IPV4_SA) if (l3->cmd & ATL2_NTC_L3_IPV6_SA) atl2_rpf_l3_v6_sa_set(hw, l3_idx, l3->src_ip6); if (l3->cmd & ATL2_NTC_L3_IPV4_DA) if (l3->cmd & ATL2_NTC_L3_IPV6_DA) atl2_rpf_l3_v6_da_set(hw, l3_idx, l3->dst_ip6); } else { WARN(1, "L3 filter invalid"); Loading @@ -2242,6 +2223,10 @@ static void atl2_update_ntuple_flt(struct atl_nic *nic, int idx) return; } cmd = l4->cmd | (l4_idx + 1) << 0x4; atl_write(hw, ATL_NTUPLE_SPORT(l4_idx), swab16(l4->src_port)); atl_write(hw, ATL_NTUPLE_DPORT(l4_idx), swab16(l4->dst_port)); atl_write(hw, ATL2_RPF_L4_FLT(l4_idx), cmd); } Loading Loading @@ -2272,6 +2257,7 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) if (!(cmd & ATL_NTC_EN)) { atl_write(hw, ATL_NTUPLE_CTRL(idx), cmd); if (nic->hw.new_rpf) atl2_update_ntuple_flt(nic, idx); return; } Loading @@ -2296,6 +2282,10 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) swab32(ntuple->dst_ip4[idx])); } /* ports are used by both new RPF and legacy RPF, but with different * locations */ if (!nic->hw.new_rpf) { if (cmd & ATL_NTC_SP) atl_write(hw, ATL_NTUPLE_SPORT(idx), swab16(ntuple->src_port[idx])); Loading @@ -2303,6 +2293,7 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) if (cmd & ATL_NTC_DP) atl_write(hw, ATL_NTUPLE_DPORT(idx), swab16(ntuple->dst_port[idx])); } if (cmd & ATL_NTC_RXQ) cmd |= 1 << ATL_NTC_ACT_SHIFT; Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_fw.c +82 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ static int __atl_fw2_wait_fw_init(struct atl_hw *hw) hw->mcp.req_high = atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH)); hw->mcp.fw_stat_addr = atl_read(hw, ATL_MCP_SCRATCH(FW_STAT_STRUCT)); hw->mcp.rpc_addr = atl_read(hw, ATL_MCP_SCRATCH(FW2_RPC_DATA)); ret = atl_read_fwstat_word(hw, atl_fw2_stat_settings_addr, &hw->mcp.fw_settings_addr); if (ret) Loading Loading @@ -380,12 +383,18 @@ static int atl_fw1_unsupported(struct atl_hw *hw) return -EOPNOTSUPP; } static int atl_fw2_restart_aneg(struct atl_hw *hw) static int __atl_fw2_restart_aneg(struct atl_hw *hw) { atl_lock_fw(hw); /* Autoneg restart is self-clearing, no need to track via * mcp->req_high */ atl_set_bits(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH), BIT(31)); return 0; } static int atl_fw2_restart_aneg(struct atl_hw *hw) { atl_lock_fw(hw); __atl_fw2_restart_aneg(hw); atl_unlock_fw(hw); return 0; } Loading Loading @@ -614,6 +623,70 @@ static int atl_fw2_set_mediadetect(struct atl_hw *hw, bool on) return ret; } static int __atl_fw2x_apply_msm_settings(struct atl_hw *hw) { uint32_t msg_id = atl_fw2_msm_settings_apply; uint32_t high_status, high_req = 0; int ret = 0; if (!(hw->mcp.caps_ex & atl_fw2_ex_caps_msm_settings_apply)) return __atl_fw2_restart_aneg(hw); ret = atl_write_mcp_mem(hw, 0, &msg_id, sizeof(msg_id), MCP_AREA_CONFIG); if (ret) { atl_dev_err("Failed to upload macsec request: %d\n", ret); atl_unlock_fw(hw); return ret; } high_req = atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH)); high_req ^= atl_fw2_fw_request; atl_write(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH), high_req); busy_wait(1000, mdelay(1), high_status, atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_RES_HIGH)), ((high_req ^ high_status) & atl_fw2_fw_request) != 0); if (((high_req ^ high_status) & atl_fw2_fw_request) != 0) { atl_dev_err("Timeout waiting for fw request\n"); atl_unlock_fw(hw); return -EIO; } return ret; } static int atl_fw2_set_pad_stripping(struct atl_hw *hw, bool on) { uint32_t msm_opts; int ret = 0; if (hw->mcp.fw_rev < 0x0300008e) return -EOPNOTSUPP; atl_lock_fw(hw); ret = atl_read_fwsettings_word(hw, atl_fw2_setings_msm_opts, &msm_opts); if (ret) goto unlock; msm_opts &= ~atl_fw2_settings_msm_opts_strip_pad; if (on) msm_opts |= BIT(atl_fw2_settings_msm_opts_strip_pad_shift); ret = atl_write_fwsettings_word(hw, atl_fw2_setings_msm_opts, msm_opts); if (ret) goto unlock; ret = __atl_fw2x_apply_msm_settings(hw); unlock: atl_unlock_fw(hw); return ret; } static int atl_fw2_send_macsec_request(struct atl_hw *hw, struct macsec_msg_fw_request *req, struct macsec_msg_fw_response *response) Loading @@ -627,11 +700,14 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, if ((hw->mcp.caps_low & atl_fw2_macsec) == 0) return -EOPNOTSUPP; atl_lock_fw(hw); /* Write macsec request to cfg memory */ ret = atl_write_mcp_mem(hw, 0, req, (sizeof(*req) + 3) & ~3, MCP_AREA_CONFIG); if (ret) { atl_dev_err("Failed to upload macsec request: %d\n", ret); atl_unlock_fw(hw); return ret; } Loading @@ -645,6 +721,7 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, ((low_req ^ low_status) & atl_fw2_macsec) != 0); if (((low_req ^ low_status) & atl_fw2_macsec) != 0) { atl_dev_err("Timeout waiting for macsec request\n"); atl_unlock_fw(hw); return -EIO; } Loading @@ -652,6 +729,7 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, ret = atl_read_rpc_mem(hw, sizeof(u32), (u32 *)(void *)response, sizeof(*response)); atl_unlock_fw(hw); return ret; } Loading Loading @@ -799,6 +877,7 @@ static struct atl_fw_ops atl_fw_ops[2] = { .set_phy_loopback = (void *)atl_fw1_unsupported, .set_mediadetect = (void *)atl_fw1_unsupported, .send_macsec_req = (void *)atl_fw1_unsupported, .set_pad_stripping = (void *)atl_fw1_unsupported, .__get_hbeat = (void *)atl_fw1_unsupported, .get_mac_addr = atl_fw1_get_mac_addr, .update_thermal = atl_fw1_unsupported, Loading @@ -818,6 +897,7 @@ static struct atl_fw_ops atl_fw_ops[2] = { .set_phy_loopback = atl_fw2_set_phy_loopback, .set_mediadetect = atl_fw2_set_mediadetect, .send_macsec_req = atl_fw2_send_macsec_request, .set_pad_stripping = atl_fw2_set_pad_stripping, .__get_hbeat = __atl_fw2_get_hbeat, .get_mac_addr = atl_fw2_get_mac_addr, .update_thermal = atl_fw2_update_thermal, Loading Loading @@ -981,9 +1061,6 @@ int atl_fw_init(struct atl_hw *hw) if (ret) return ret; mcp->fw_stat_addr = atl_read(hw, ATL_MCP_SCRATCH(FW_STAT_STRUCT)); mcp->rpc_addr = atl_read(hw, ATL_MCP_SCRATCH(FW2_RPC_DATA)); ret = mcp->ops->__get_hbeat(hw, &mcp->phy_hbeat); if (ret) return ret; Loading Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl2_fw.c +32 −10 Original line number Diff line number Diff line Loading @@ -221,7 +221,7 @@ static int __atl2_fw_wait_init(struct atl_hw *hw) atl2_shared_buffer_write(hw, link_control, link_control); atl2_shared_buffer_get(hw, mtu, mtu); mtu = ATL_MAX_MTU; mtu = ATL_MAX_MTU + ETH_FCS_LEN + ETH_HLEN; atl2_shared_buffer_write(hw, mtu, mtu); return atl2_shared_buffer_finish_ack(hw); Loading Loading @@ -308,11 +308,11 @@ static void atl2_set_eee(struct atl_link_state *lstate, return; } link_options->eee_100M = eee_advertized & BIT(atl_link_type_idx_100m); link_options->eee_1G = eee_advertized & BIT(atl_link_type_idx_1g); link_options->eee_2P5G = eee_advertized & BIT(atl_link_type_idx_2p5g); link_options->eee_5G = eee_advertized & BIT(atl_link_type_idx_5g); link_options->eee_10G = eee_advertized & BIT(atl_link_type_idx_10g); link_options->eee_100M = !!(eee_advertized & BIT(atl_link_type_idx_100m)); link_options->eee_1G = !!(eee_advertized & BIT(atl_link_type_idx_1g)); link_options->eee_2P5G = !!(eee_advertized & BIT(atl_link_type_idx_2p5g)); link_options->eee_5G = !!(eee_advertized & BIT(atl_link_type_idx_5g)); link_options->eee_10G = !!(eee_advertized & BIT(atl_link_type_idx_10g)); } /* fw lock must be held */ Loading Loading @@ -387,6 +387,8 @@ static u32 a2_fw_caps_to_mask(struct device_link_caps_s *link_caps) supported |= BIT(atl_link_type_idx_2p5g) << ATL_EEE_BIT_OFFT; if (link_caps->eee_1G) supported |= BIT(atl_link_type_idx_1g) << ATL_EEE_BIT_OFFT; if (link_caps->eee_100M) supported |= BIT(atl_link_type_idx_100m) << ATL_EEE_BIT_OFFT; return supported; } Loading Loading @@ -422,6 +424,8 @@ static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps) rate |= BIT(atl_link_type_idx_2p5g) << ATL_EEE_BIT_OFFT; if (lkp_link_caps->eee_1G) rate |= BIT(atl_link_type_idx_1g) << ATL_EEE_BIT_OFFT; if (lkp_link_caps->eee_100M) rate |= BIT(atl_link_type_idx_100m) << ATL_EEE_BIT_OFFT; return rate; } Loading Loading @@ -679,10 +683,10 @@ static int atl2_fw_update_thermal(struct atl_hw *hw) atl_lock_fw(hw); atl2_shared_buffer_get(hw, thermal_shutdown, thermal_shutdown); thermal_shutdown.enable = enable; thermal_shutdown.shutdown_temperature = hw->thermal.crit; thermal_shutdown.warning_temperature = hw->thermal.high; thermal_shutdown.cold_temperature = hw->thermal.low; thermal_shutdown.shutdown_enable = enable; thermal_shutdown.shutdown_temp_threshold = hw->thermal.crit; thermal_shutdown.warning_hot_tempThreshold = hw->thermal.high; thermal_shutdown.warning_cold_temp_threshold = hw->thermal.low; atl2_shared_buffer_write(hw, thermal_shutdown, thermal_shutdown); ret = atl2_shared_buffer_finish_ack(hw); Loading @@ -696,6 +700,23 @@ static int atl2_fw_update_thermal(struct atl_hw *hw) return ret; } static int atl2_fw_set_pad_stripping(struct atl_hw *hw, bool on) { struct link_control_s link_control; int err = 0; atl_lock_fw(hw); atl2_shared_buffer_get(hw, link_control, link_control); link_control.enable_frame_padding_removal_rx = on; atl2_shared_buffer_write(hw, link_control, link_control); err = atl2_shared_buffer_finish_ack(hw); atl_unlock_fw(hw); return err; } static int atl2_fw_unsupported(struct atl_hw *hw) { return -ENOTSUPP; Loading Loading @@ -723,6 +744,7 @@ static struct atl_fw_ops atl2_fw_ops = { .get_phy_temperature = atl2_fw_get_phy_temperature, .set_mediadetect = (void *)atl2_fw_unsupported, .send_macsec_req = (void *)atl2_fw_unsupported, .set_pad_stripping = atl2_fw_set_pad_stripping, .get_mac_addr = atl2_fw_get_mac_addr, .__get_hbeat = __atl2_fw_get_hbeat, .set_phy_loopback = atl2_fw_set_phy_loopback, Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl2_fw.h +5 −6 Original line number Diff line number Diff line Loading @@ -66,14 +66,13 @@ struct link_control_s { }; struct thermal_shutdown_s { uint32_t enable:1; uint32_t shutdown_enable :1; uint32_t warning_enable :1; uint32_t rsvd:6; uint32_t cold_temperature:8; uint32_t warning_temperature:8; uint32_t shutdown_temperature:8; uint32_t shutdown_temp_threshold :8; uint32_t warning_cold_temp_threshold :8; uint32_t warning_hot_tempThreshold :8; }; struct mac_address_s { Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h +13 −10 Original line number Diff line number Diff line Loading @@ -18,10 +18,9 @@ #include <linux/netdevice.h> #include <linux/moduleparam.h> #define ATL_VERSION "1.1.0" #define ATL_VERSION "1.1.4" struct atl_nic; enum atl_fwd_notify; #include "atl_compat.h" #include "atl_hw.h" Loading Loading @@ -90,8 +89,8 @@ enum atl2_ntuple_cmd { ATL2_NTC_L3_IPV6_PROTO_SHIFT = 0x18, ATL2_NTC_L4_EN = BIT(0), /* Filter enabled */ ATL2_NTC_L4_SP = BIT(1), ATL2_NTC_L4_DP = BIT(2), ATL2_NTC_L4_DP = BIT(1), ATL2_NTC_L4_SP = BIT(2), }; struct atl2_rxf_l3 { Loading @@ -106,14 +105,14 @@ struct atl2_rxf_l3 { }; }; u16 proto; u16 cmd; u32 cmd; u16 usage; }; struct atl2_rxf_l4 { __be16 dst_port; __be16 src_port; u16 cmd; u32 cmd; u16 usage; }; Loading Loading @@ -210,7 +209,7 @@ struct atl_fwd { struct blocking_notifier_head nh_clients; }; #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) struct atl_fwdnl { struct atl_desc_ring ring_desc[ATL_NUM_FWD_RINGS * 2]; /* State of forced redirections */ Loading Loading @@ -241,10 +240,10 @@ struct atl_nic { spinlock_t stats_lock; struct work_struct work; #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) struct atl_fwd fwd; #endif #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) struct atl_fwdnl fwdnl; #endif Loading Loading @@ -383,12 +382,16 @@ int atl_update_eth_stats(struct atl_nic *nic); void atl_adjust_eth_stats(struct atl_ether_stats *stats, struct atl_ether_stats *base, bool add); void atl_fwd_release_rings(struct atl_nic *nic); #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) enum atl_fwd_notify; int atl_fwd_suspend_rings(struct atl_nic *nic); int atl_fwd_resume_rings(struct atl_nic *nic); void atl_fwd_notify(struct atl_nic *nic, enum atl_fwd_notify notif, void *data); #else static inline int atl_fwd_suspend_rings(struct atl_nic *nic) { return 0; } static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; } static inline void atl_fwd_notify(struct atl_nic *nic, enum atl_fwd_notify notif, void *data) {} #endif int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay); void atl_refresh_rxfs(struct atl_nic *nic); Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_ethtool.c +40 −49 Original line number Diff line number Diff line Loading @@ -190,9 +190,9 @@ static int atl_set_fixed_speed(struct atl_hw *hw, unsigned int speed, if (lstate->eee_enabled) { atl_link_to_kernel(lstate->supported >> ATL_EEE_BIT_OFFT, &tmp, true); &tmp, false); /* advertize the supported links */ tmp = atl_kernel_to_link(&tmp, true); tmp = atl_kernel_to_link(&tmp, false); lstate->advertized |= tmp << ATL_EEE_BIT_OFFT; } Loading Loading @@ -425,7 +425,7 @@ static int atl_set_pauseparam(struct net_device *ndev, struct atl_link_state *lstate = &hw->link_state; struct atl_fc_state *fc = &lstate->fc; if (atl_fw_major(hw) < 2) if ((hw->chip_id == ATL_ATLANTIC) && (atl_fw_major(hw) < 2)) return -EOPNOTSUPP; if (pause->autoneg) Loading Loading @@ -459,6 +459,7 @@ static int atl_get_eee(struct net_device *ndev, struct ethtool_eee *eee) eee->eee_enabled = eee->tx_lpi_enabled = lstate->eee_enabled; eee->eee_active = lstate->eee; if (lstate->link) ret = atl_get_lpi_timer(nic, &eee->tx_lpi_timer); return ret; Loading @@ -469,31 +470,28 @@ static int atl_set_eee(struct net_device *ndev, struct ethtool_eee *eee) struct atl_nic *nic = netdev_priv(ndev); struct atl_hw *hw = &nic->hw; struct atl_link_state *lstate = &hw->link_state; uint32_t tmp = 0; uint32_t lpi_timer = 0; unsigned long tmp = 0; if (atl_fw_major(hw) < 2) if ((hw->chip_id == ATL_ATLANTIC) && (atl_fw_major(hw) < 2)) return -EOPNOTSUPP; atl_get_lpi_timer(nic, &tmp); if (eee->tx_lpi_timer != tmp) atl_get_lpi_timer(nic, &lpi_timer); if (eee->tx_lpi_timer != lpi_timer) return -EOPNOTSUPP; lstate->eee_enabled = eee->eee_enabled; if (lstate->eee_enabled) { atl_link_to_kernel(lstate->supported >> ATL_EEE_BIT_OFFT, (unsigned long *)&tmp, true); &tmp, false); if (eee->advertised & ~tmp) return -EINVAL; /* advertize the requested link or all supported */ if (eee->advertised) tmp = atl_kernel_to_link( (unsigned long *)&eee->advertised, true); else tmp = atl_kernel_to_link( (unsigned long *)&tmp, true); tmp = eee->advertised; tmp = atl_kernel_to_link(&tmp, false); } lstate->advertized &= ~ATL_EEE_MASK; Loading Loading @@ -735,7 +733,7 @@ static int atl_get_sset_count(struct net_device *ndev, int sset) return ARRAY_SIZE(tx_stat_descs) * (nic->nvecs + 1) + ARRAY_SIZE(rx_stat_descs) * (nic->nvecs + 1) + ARRAY_SIZE(eth_stat_descs) #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) + ARRAY_SIZE(tx_stat_descs) * hweight_long(nic->fwd.ring_map[ATL_FWDIR_TX]) + ARRAY_SIZE(rx_stat_descs) * Loading Loading @@ -800,7 +798,7 @@ static void atl_get_strings(struct net_device *ndev, uint32_t sset, atl_copy_stats_string_set(&p, prefix); } #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) for (i = 0; i < ATL_NUM_FWD_RINGS; i++) { snprintf(prefix, sizeof(prefix), "fwd_ring_%d_", i); Loading Loading @@ -908,7 +906,7 @@ static void atl_get_ethtool_stats(struct net_device *ndev, atl_write_stats(&tmp.rx, rx_stat_descs, data, uint64_t); } #ifdef CONFIG_ATLFWD_FWD_NETLINK #if IS_ENABLED(CONFIG_ATLFWD_FWD_NETLINK) for (i = 0; i < ATL_NUM_FWD_RINGS; i++) { struct atl_ring_stats tmp; Loading Loading @@ -1045,27 +1043,10 @@ static int atl_set_pad_stripping(struct atl_nic *nic, bool on) { struct atl_hw *hw = &nic->hw; int ret; uint32_t msm_opts; if (hw->mcp.fw_rev < 0x0300008e) return -EOPNOTSUPP; ret = atl_read_fwsettings_word(hw, atl_fw2_setings_msm_opts, &msm_opts); if (ret) return ret; ret = hw->mcp.ops->set_pad_stripping(hw, on); msm_opts &= ~atl_fw2_settings_msm_opts_strip_pad; msm_opts |= !!on << atl_fw2_settings_msm_opts_strip_pad_shift; ret = atl_write_fwsettings_word(hw, atl_fw2_setings_msm_opts, msm_opts); if (ret) return ret; /* Restart aneg to make FW apply the new settings */ hw->mcp.ops->restart_aneg(hw); return 0; } int atl_set_media_detect(struct atl_nic *nic, bool on) Loading Loading @@ -1408,7 +1389,7 @@ static int atl_rxf_check_ring(struct atl_nic *nic, uint32_t ring) if (ring < nic->nvecs || ring == ATL_RXF_RING_ANY) return 0; #ifdef CONFIG_ATLFWD_FWD #if IS_ENABLED(CONFIG_ATLFWD_FWD) if (test_bit(ring, &nic->fwd.ring_map[ATL_FWDIR_RX])) return 0; #endif Loading Loading @@ -1791,8 +1772,8 @@ static void atl2_rxf_set_ntuple(struct atl_nic *nic, if (ntuple->cmd[idx] & ATL_NTC_PROTO) l3.cmd |= ntuple->cmd[idx] & ATL_NTC_V6 ? ATL2_NTC_L3_IPV6_PROTO : ATL2_NTC_L3_IPV4_PROTO; ATL2_NTC_L3_IPV6_PROTO | ATL2_NTC_L3_IPV6_EN : ATL2_NTC_L3_IPV4_PROTO | ATL2_NTC_L3_IPV4_EN; switch (ntuple->cmd[idx] & ATL_NTC_L4_MASK) { case ATL_NTC_L4_TCP: Loading Loading @@ -2220,9 +2201,9 @@ static void atl2_update_ntuple_flt(struct atl_nic *nic, int idx) mask |= ATL2_RPF_TAG_L3_V6_MASK; cmd |= (l3_idx + 1) << 0x14; if (l3->cmd & ATL2_NTC_L3_IPV4_SA) if (l3->cmd & ATL2_NTC_L3_IPV6_SA) atl2_rpf_l3_v6_sa_set(hw, l3_idx, l3->src_ip6); if (l3->cmd & ATL2_NTC_L3_IPV4_DA) if (l3->cmd & ATL2_NTC_L3_IPV6_DA) atl2_rpf_l3_v6_da_set(hw, l3_idx, l3->dst_ip6); } else { WARN(1, "L3 filter invalid"); Loading @@ -2242,6 +2223,10 @@ static void atl2_update_ntuple_flt(struct atl_nic *nic, int idx) return; } cmd = l4->cmd | (l4_idx + 1) << 0x4; atl_write(hw, ATL_NTUPLE_SPORT(l4_idx), swab16(l4->src_port)); atl_write(hw, ATL_NTUPLE_DPORT(l4_idx), swab16(l4->dst_port)); atl_write(hw, ATL2_RPF_L4_FLT(l4_idx), cmd); } Loading Loading @@ -2272,6 +2257,7 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) if (!(cmd & ATL_NTC_EN)) { atl_write(hw, ATL_NTUPLE_CTRL(idx), cmd); if (nic->hw.new_rpf) atl2_update_ntuple_flt(nic, idx); return; } Loading @@ -2296,6 +2282,10 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) swab32(ntuple->dst_ip4[idx])); } /* ports are used by both new RPF and legacy RPF, but with different * locations */ if (!nic->hw.new_rpf) { if (cmd & ATL_NTC_SP) atl_write(hw, ATL_NTUPLE_SPORT(idx), swab16(ntuple->src_port[idx])); Loading @@ -2303,6 +2293,7 @@ void atl_update_ntuple_flt(struct atl_nic *nic, int idx) if (cmd & ATL_NTC_DP) atl_write(hw, ATL_NTUPLE_DPORT(idx), swab16(ntuple->dst_port[idx])); } if (cmd & ATL_NTC_RXQ) cmd |= 1 << ATL_NTC_ACT_SHIFT; Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_fw.c +82 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ static int __atl_fw2_wait_fw_init(struct atl_hw *hw) hw->mcp.req_high = atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH)); hw->mcp.fw_stat_addr = atl_read(hw, ATL_MCP_SCRATCH(FW_STAT_STRUCT)); hw->mcp.rpc_addr = atl_read(hw, ATL_MCP_SCRATCH(FW2_RPC_DATA)); ret = atl_read_fwstat_word(hw, atl_fw2_stat_settings_addr, &hw->mcp.fw_settings_addr); if (ret) Loading Loading @@ -380,12 +383,18 @@ static int atl_fw1_unsupported(struct atl_hw *hw) return -EOPNOTSUPP; } static int atl_fw2_restart_aneg(struct atl_hw *hw) static int __atl_fw2_restart_aneg(struct atl_hw *hw) { atl_lock_fw(hw); /* Autoneg restart is self-clearing, no need to track via * mcp->req_high */ atl_set_bits(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH), BIT(31)); return 0; } static int atl_fw2_restart_aneg(struct atl_hw *hw) { atl_lock_fw(hw); __atl_fw2_restart_aneg(hw); atl_unlock_fw(hw); return 0; } Loading Loading @@ -614,6 +623,70 @@ static int atl_fw2_set_mediadetect(struct atl_hw *hw, bool on) return ret; } static int __atl_fw2x_apply_msm_settings(struct atl_hw *hw) { uint32_t msg_id = atl_fw2_msm_settings_apply; uint32_t high_status, high_req = 0; int ret = 0; if (!(hw->mcp.caps_ex & atl_fw2_ex_caps_msm_settings_apply)) return __atl_fw2_restart_aneg(hw); ret = atl_write_mcp_mem(hw, 0, &msg_id, sizeof(msg_id), MCP_AREA_CONFIG); if (ret) { atl_dev_err("Failed to upload macsec request: %d\n", ret); atl_unlock_fw(hw); return ret; } high_req = atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH)); high_req ^= atl_fw2_fw_request; atl_write(hw, ATL_MCP_SCRATCH(FW2_LINK_REQ_HIGH), high_req); busy_wait(1000, mdelay(1), high_status, atl_read(hw, ATL_MCP_SCRATCH(FW2_LINK_RES_HIGH)), ((high_req ^ high_status) & atl_fw2_fw_request) != 0); if (((high_req ^ high_status) & atl_fw2_fw_request) != 0) { atl_dev_err("Timeout waiting for fw request\n"); atl_unlock_fw(hw); return -EIO; } return ret; } static int atl_fw2_set_pad_stripping(struct atl_hw *hw, bool on) { uint32_t msm_opts; int ret = 0; if (hw->mcp.fw_rev < 0x0300008e) return -EOPNOTSUPP; atl_lock_fw(hw); ret = atl_read_fwsettings_word(hw, atl_fw2_setings_msm_opts, &msm_opts); if (ret) goto unlock; msm_opts &= ~atl_fw2_settings_msm_opts_strip_pad; if (on) msm_opts |= BIT(atl_fw2_settings_msm_opts_strip_pad_shift); ret = atl_write_fwsettings_word(hw, atl_fw2_setings_msm_opts, msm_opts); if (ret) goto unlock; ret = __atl_fw2x_apply_msm_settings(hw); unlock: atl_unlock_fw(hw); return ret; } static int atl_fw2_send_macsec_request(struct atl_hw *hw, struct macsec_msg_fw_request *req, struct macsec_msg_fw_response *response) Loading @@ -627,11 +700,14 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, if ((hw->mcp.caps_low & atl_fw2_macsec) == 0) return -EOPNOTSUPP; atl_lock_fw(hw); /* Write macsec request to cfg memory */ ret = atl_write_mcp_mem(hw, 0, req, (sizeof(*req) + 3) & ~3, MCP_AREA_CONFIG); if (ret) { atl_dev_err("Failed to upload macsec request: %d\n", ret); atl_unlock_fw(hw); return ret; } Loading @@ -645,6 +721,7 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, ((low_req ^ low_status) & atl_fw2_macsec) != 0); if (((low_req ^ low_status) & atl_fw2_macsec) != 0) { atl_dev_err("Timeout waiting for macsec request\n"); atl_unlock_fw(hw); return -EIO; } Loading @@ -652,6 +729,7 @@ static int atl_fw2_send_macsec_request(struct atl_hw *hw, ret = atl_read_rpc_mem(hw, sizeof(u32), (u32 *)(void *)response, sizeof(*response)); atl_unlock_fw(hw); return ret; } Loading Loading @@ -799,6 +877,7 @@ static struct atl_fw_ops atl_fw_ops[2] = { .set_phy_loopback = (void *)atl_fw1_unsupported, .set_mediadetect = (void *)atl_fw1_unsupported, .send_macsec_req = (void *)atl_fw1_unsupported, .set_pad_stripping = (void *)atl_fw1_unsupported, .__get_hbeat = (void *)atl_fw1_unsupported, .get_mac_addr = atl_fw1_get_mac_addr, .update_thermal = atl_fw1_unsupported, Loading @@ -818,6 +897,7 @@ static struct atl_fw_ops atl_fw_ops[2] = { .set_phy_loopback = atl_fw2_set_phy_loopback, .set_mediadetect = atl_fw2_set_mediadetect, .send_macsec_req = atl_fw2_send_macsec_request, .set_pad_stripping = atl_fw2_set_pad_stripping, .__get_hbeat = __atl_fw2_get_hbeat, .get_mac_addr = atl_fw2_get_mac_addr, .update_thermal = atl_fw2_update_thermal, Loading Loading @@ -981,9 +1061,6 @@ int atl_fw_init(struct atl_hw *hw) if (ret) return ret; mcp->fw_stat_addr = atl_read(hw, ATL_MCP_SCRATCH(FW_STAT_STRUCT)); mcp->rpc_addr = atl_read(hw, ATL_MCP_SCRATCH(FW2_RPC_DATA)); ret = mcp->ops->__get_hbeat(hw, &mcp->phy_hbeat); if (ret) return ret; Loading