Lines Matching full:pf
60 static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf) in ice_get_ctrl_pf() argument
62 return !pf->adapter ? NULL : pf->adapter->ctrl_pf; in ice_get_ctrl_pf()
65 static struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf) in ice_get_ctrl_ptp() argument
67 struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf); in ice_get_ctrl_ptp()
74 * @pf: Board private structure
80 static int ice_ptp_find_pin_idx(struct ice_pf *pf, enum ptp_pin_function func, in ice_ptp_find_pin_idx() argument
83 const struct ptp_clock_info *info = &pf->ptp.info; in ice_ptp_find_pin_idx()
97 * @pf: Board private structure
101 static void ice_ptp_update_sma_data(struct ice_pf *pf, unsigned int sma_pins[], in ice_ptp_update_sma_data() argument
147 dev_dbg(ice_pf_to_dev(pf), "%s, %s\n", state1, state2); in ice_ptp_update_sma_data()
152 * @pf: Board private structure
156 static int ice_ptp_set_sma_cfg(struct ice_pf *pf) in ice_ptp_set_sma_cfg() argument
158 const struct ice_ptp_pin_desc *ice_pins = pf->ptp.ice_pin_desc; in ice_ptp_set_sma_cfg()
159 struct ptp_pin_desc *pins = pf->ptp.pin_desc; in ice_ptp_set_sma_cfg()
165 err = ice_read_sma_ctrl(&pf->hw, &data); in ice_ptp_set_sma_cfg()
170 for (int i = 0; i < pf->ptp.info.n_pins; i++) in ice_ptp_set_sma_cfg()
186 ice_ptp_update_sma_data(pf, sma_pins, &data); in ice_ptp_set_sma_cfg()
187 return ice_write_sma_ctrl(&pf->hw, data); in ice_ptp_set_sma_cfg()
192 * @pf: Board private structure
197 static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf) in ice_ptp_cfg_tx_interrupt() argument
199 struct ice_hw *hw = &pf->hw; in ice_ptp_cfg_tx_interrupt()
203 switch (pf->ptp.tx_interrupt_mode) { in ice_ptp_cfg_tx_interrupt()
216 enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON; in ice_ptp_cfg_tx_interrupt()
231 * @pf: The PF pointer to search in
234 static void ice_set_rx_tstamp(struct ice_pf *pf, bool on) in ice_set_rx_tstamp() argument
239 vsi = ice_get_main_vsi(pf); in ice_set_rx_tstamp()
253 * @pf: Board private structure
259 static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf) in ice_ptp_disable_timestamp_mode() argument
261 struct ice_hw *hw = &pf->hw; in ice_ptp_disable_timestamp_mode()
268 ice_set_rx_tstamp(pf, false); in ice_ptp_disable_timestamp_mode()
273 * @pf: Board private structure
278 void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) in ice_ptp_restore_timestamp_mode() argument
280 struct ice_hw *hw = &pf->hw; in ice_ptp_restore_timestamp_mode()
283 ice_ptp_cfg_tx_interrupt(pf); in ice_ptp_restore_timestamp_mode()
285 enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL; in ice_ptp_restore_timestamp_mode()
286 ice_set_rx_tstamp(pf, enable_rx); in ice_ptp_restore_timestamp_mode()
297 * @pf: Board private structure
301 u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf, in ice_ptp_read_src_clk_reg() argument
304 struct ice_hw *hw = &pf->hw; in ice_ptp_read_src_clk_reg()
309 guard(spinlock)(&pf->adapter->ptp_gltsyn_time_lock); in ice_ptp_read_src_clk_reg()
412 * @pf: Board private structure
436 static u64 ice_ptp_extend_40b_ts(struct ice_pf *pf, u64 in_tstamp) in ice_ptp_extend_40b_ts() argument
442 discard_time = pf->ptp.cached_phc_jiffies + msecs_to_jiffies(2000); in ice_ptp_extend_40b_ts()
444 pf->ptp.tx_hwtstamp_discarded++; in ice_ptp_extend_40b_ts()
448 return ice_ptp_extend_32b_ts(pf->ptp.cached_phc_time, in ice_ptp_extend_40b_ts()
480 struct ice_pf *pf; in ice_ptp_req_tx_single_tstamp() local
486 pf = ptp_port_to_pf(ptp_port); in ice_ptp_req_tx_single_tstamp()
487 params = &pf->hw.ptp.phy.e810; in ice_ptp_req_tx_single_tstamp()
492 pf->ptp.tx_hwtstamp_timeouts++; in ice_ptp_req_tx_single_tstamp()
508 /* Write TS index to read to the PF register so the FW can read it */ in ice_ptp_req_tx_single_tstamp()
509 wr32(&pf->hw, REG_LL_PROXY_H, in ice_ptp_req_tx_single_tstamp()
532 struct ice_pf *pf; in ice_ptp_complete_tx_single_tstamp() local
539 pf = ptp_port_to_pf(ptp_port); in ice_ptp_complete_tx_single_tstamp()
540 dev = ice_pf_to_dev(pf); in ice_ptp_complete_tx_single_tstamp()
541 params = &pf->hw.ptp.phy.e810; in ice_ptp_complete_tx_single_tstamp()
552 raw_tstamp = rd32(&pf->hw, REG_LL_PROXY_L); in ice_ptp_complete_tx_single_tstamp()
554 reg_ll_high = rd32(&pf->hw, REG_LL_PROXY_H); in ice_ptp_complete_tx_single_tstamp()
565 dev_err(ice_pf_to_dev(pf), "Failed to get the Tx tstamp - FW not ready"); in ice_ptp_complete_tx_single_tstamp()
594 tstamp = ice_ptp_extend_40b_ts(pf, raw_tstamp); in ice_ptp_complete_tx_single_tstamp()
656 struct ice_pf *pf; in ice_ptp_process_tx_tstamp() local
664 pf = ptp_port_to_pf(ptp_port); in ice_ptp_process_tx_tstamp()
665 hw = &pf->hw; in ice_ptp_process_tx_tstamp()
689 pf->ptp.tx_hwtstamp_timeouts++; in ice_ptp_process_tx_tstamp()
752 tstamp = ice_ptp_extend_40b_ts(pf, raw_tstamp); in ice_ptp_process_tx_tstamp()
765 * @pf: Board private structure
767 static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) in ice_ptp_tx_tstamp_owner() argument
772 mutex_lock(&pf->adapter->ports.lock); in ice_ptp_tx_tstamp_owner()
773 list_for_each_entry(port, &pf->adapter->ports.ports, list_node) { in ice_ptp_tx_tstamp_owner()
781 mutex_unlock(&pf->adapter->ports.lock); in ice_ptp_tx_tstamp_owner()
783 for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) { in ice_ptp_tx_tstamp_owner()
788 err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); in ice_ptp_tx_tstamp_owner()
865 * @pf: Board private structure
871 ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx) in ice_ptp_flush_tx_tracker() argument
873 struct ice_hw *hw = &pf->hw; in ice_ptp_flush_tx_tracker()
881 dev_dbg(ice_pf_to_dev(pf), "Failed to get the Tx tstamp ready bitmap for block %u, err %d\n", in ice_ptp_flush_tx_tracker()
906 pf->ptp.tx_hwtstamp_flushed++; in ice_ptp_flush_tx_tracker()
936 * @pf: Board private structure
942 ice_ptp_flush_all_tx_tracker(struct ice_pf *pf) in ice_ptp_flush_all_tx_tracker() argument
946 list_for_each_entry(port, &pf->adapter->ports.ports, list_node) in ice_ptp_flush_all_tx_tracker()
952 * @pf: Board private structure
958 ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx) in ice_ptp_release_tx_tracker() argument
967 synchronize_irq(pf->oicr_irq.virq); in ice_ptp_release_tx_tracker()
969 ice_ptp_flush_tx_tracker(pf, tx); in ice_ptp_release_tx_tracker()
985 * @pf: Board private structure
996 static int ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, in ice_ptp_init_tx_e82x() argument
1009 * @pf: Board private structure
1013 * Initialize the Tx timestamp tracker for this PF. For all PHYs except E82X,
1018 static int ice_ptp_init_tx(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) in ice_ptp_init_tx() argument
1028 tx->has_ready_bitmap = pf->hw.mac_type != ICE_MAC_E810; in ice_ptp_init_tx()
1035 * @pf: Board specific private structure
1037 * This function updates the system time values which are cached in the PF
1043 * Note that the cached copy in the PF PTP structure is always updated, even
1048 * * -EAGAIN - PF was busy, need to reschedule the update
1050 static int ice_ptp_update_cached_phctime(struct ice_pf *pf) in ice_ptp_update_cached_phctime() argument
1052 struct device *dev = ice_pf_to_dev(pf); in ice_ptp_update_cached_phctime()
1057 update_before = pf->ptp.cached_phc_jiffies + msecs_to_jiffies(2000); in ice_ptp_update_cached_phctime()
1058 if (pf->ptp.cached_phc_time && in ice_ptp_update_cached_phctime()
1060 unsigned long time_taken = jiffies - pf->ptp.cached_phc_jiffies; in ice_ptp_update_cached_phctime()
1064 pf->ptp.late_cached_phc_updates++; in ice_ptp_update_cached_phctime()
1068 systime = ice_ptp_read_src_clk_reg(pf, NULL); in ice_ptp_update_cached_phctime()
1070 /* Update the cached PHC time stored in the PF structure */ in ice_ptp_update_cached_phctime()
1071 WRITE_ONCE(pf->ptp.cached_phc_time, systime); in ice_ptp_update_cached_phctime()
1072 WRITE_ONCE(pf->ptp.cached_phc_jiffies, jiffies); in ice_ptp_update_cached_phctime()
1074 if (test_and_set_bit(ICE_CFG_BUSY, pf->state)) in ice_ptp_update_cached_phctime()
1077 ice_for_each_vsi(pf, i) { in ice_ptp_update_cached_phctime()
1078 struct ice_vsi *vsi = pf->vsi[i]; in ice_ptp_update_cached_phctime()
1093 clear_bit(ICE_CFG_BUSY, pf->state); in ice_ptp_update_cached_phctime()
1100 * @pf: Board specific private structure
1104 * timestamps as stale and updates the cached PHC time for both the PF and Rx
1111 static void ice_ptp_reset_cached_phctime(struct ice_pf *pf) in ice_ptp_reset_cached_phctime() argument
1113 struct device *dev = ice_pf_to_dev(pf); in ice_ptp_reset_cached_phctime()
1119 err = ice_ptp_update_cached_phctime(pf); in ice_ptp_reset_cached_phctime()
1129 kthread_queue_delayed_work(pf->ptp.kworker, &pf->ptp.work, in ice_ptp_reset_cached_phctime()
1138 ice_ptp_mark_tx_tracker_stale(&pf->ptp.port.tx); in ice_ptp_reset_cached_phctime()
1143 * @pf: Board private structure
1148 static int ice_ptp_write_init(struct ice_pf *pf, struct timespec64 *ts) in ice_ptp_write_init() argument
1151 struct ice_hw *hw = &pf->hw; in ice_ptp_write_init()
1158 * @pf: Board private structure
1164 static int ice_ptp_write_adj(struct ice_pf *pf, s32 adj) in ice_ptp_write_adj() argument
1166 struct ice_hw *hw = &pf->hw; in ice_ptp_write_adj()
1173 * @pf: Board private structure
1180 static u64 ice_base_incval(struct ice_pf *pf) in ice_base_incval() argument
1182 struct ice_hw *hw = &pf->hw; in ice_base_incval()
1187 dev_dbg(ice_pf_to_dev(pf), "PTP: using base increment value of 0x%016llx\n", in ice_base_incval()
1201 struct ice_pf *pf; in ice_ptp_check_tx_fifo() local
1206 pf = ptp_port_to_pf(port); in ice_ptp_check_tx_fifo()
1207 hw = &pf->hw; in ice_ptp_check_tx_fifo()
1221 dev_err(ice_pf_to_dev(pf), "PTP failed to check port %d Tx FIFO, err %d\n", in ice_ptp_check_tx_fifo()
1238 dev_dbg(ice_pf_to_dev(pf), "Try %d, port %d FIFO not empty\n", in ice_ptp_check_tx_fifo()
1242 dev_dbg(ice_pf_to_dev(pf), in ice_ptp_check_tx_fifo()
1271 struct ice_pf *pf; in ice_ptp_wait_for_offsets() local
1277 pf = ptp_port_to_pf(port); in ice_ptp_wait_for_offsets()
1278 hw = &pf->hw; in ice_ptp_wait_for_offsets()
1280 if (ice_is_reset_in_progress(pf->state)) { in ice_ptp_wait_for_offsets()
1282 kthread_queue_delayed_work(pf->ptp.kworker, in ice_ptp_wait_for_offsets()
1294 kthread_queue_delayed_work(pf->ptp.kworker, in ice_ptp_wait_for_offsets()
1308 struct ice_pf *pf = ptp_port_to_pf(ptp_port); in ice_ptp_port_phy_stop() local
1310 struct ice_hw *hw = &pf->hw; in ice_ptp_port_phy_stop()
1332 dev_err(ice_pf_to_dev(pf), "PTP failed to set PHY port %d down, err %d\n", in ice_ptp_port_phy_stop()
1351 struct ice_pf *pf = ptp_port_to_pf(ptp_port); in ice_ptp_port_phy_restart() local
1353 struct ice_hw *hw = &pf->hw; in ice_ptp_port_phy_restart()
1389 kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work, in ice_ptp_port_phy_restart()
1400 dev_err(ice_pf_to_dev(pf), "PTP failed to set PHY port %d up, err %d\n", in ice_ptp_port_phy_restart()
1410 * @pf: Board private structure
1413 void ice_ptp_link_change(struct ice_pf *pf, bool linkup) in ice_ptp_link_change() argument
1416 struct ice_hw *hw = &pf->hw; in ice_ptp_link_change()
1418 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_link_change()
1421 ptp_port = &pf->ptp.port; in ice_ptp_link_change()
1427 if (pf->hw.reset_ongoing) in ice_ptp_link_change()
1440 dev_warn(ice_pf_to_dev(pf), "%s: Unknown PHY type\n", __func__); in ice_ptp_link_change()
1446 * @pf: PF private structure
1457 static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold) in ice_ptp_cfg_phy_interrupt() argument
1459 struct device *dev = ice_pf_to_dev(pf); in ice_ptp_cfg_phy_interrupt()
1460 struct ice_hw *hw = &pf->hw; in ice_ptp_cfg_phy_interrupt()
1509 * @pf: Board private structure
1511 static void ice_ptp_reset_phy_timestamping(struct ice_pf *pf) in ice_ptp_reset_phy_timestamping() argument
1513 ice_ptp_port_phy_restart(&pf->ptp.port); in ice_ptp_reset_phy_timestamping()
1518 * @pf: Board private structure
1520 static void ice_ptp_restart_all_phy(struct ice_pf *pf) in ice_ptp_restart_all_phy() argument
1524 list_for_each(entry, &pf->adapter->ports.ports) { in ice_ptp_restart_all_phy()
1544 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_adjfine() local
1545 struct ice_hw *hw = &pf->hw; in ice_ptp_adjfine()
1549 incval = adjust_by_scaled_ppm(ice_base_incval(pf), scaled_ppm); in ice_ptp_adjfine()
1552 dev_err(ice_pf_to_dev(pf), "PTP failed to set incval, err %d\n", in ice_ptp_adjfine()
1562 * @pf: Board private structure
1564 void ice_ptp_extts_event(struct ice_pf *pf) in ice_ptp_extts_event() argument
1567 struct ice_hw *hw = &pf->hw; in ice_ptp_extts_event()
1572 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_extts_event()
1585 if (!(pf->ptp.ext_ts_irq & (1 << chan))) in ice_ptp_extts_event()
1593 pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, chan); in ice_ptp_extts_event()
1597 desc = &pf->ptp.ice_pin_desc[pin_desc_idx]; in ice_ptp_extts_event()
1603 pf->ptp.ext_ts_irq &= ~(1 << chan); in ice_ptp_extts_event()
1604 ptp_clock_event(pf->ptp.clock, &event); in ice_ptp_extts_event()
1610 * @pf: Board private structure
1618 static int ice_ptp_cfg_extts(struct ice_pf *pf, struct ptp_extts_request *rq, in ice_ptp_cfg_extts() argument
1622 struct ice_hw *hw = &pf->hw; in ice_ptp_cfg_extts()
1638 pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_EXTTS, chan); in ice_ptp_cfg_extts()
1642 gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[0]; in ice_ptp_cfg_extts()
1672 for (unsigned int i = 0; i < pf->ptp.info.n_ext_ts; i++) in ice_ptp_cfg_extts()
1673 if ((pf->ptp.extts_rqs[i].flags & in ice_ptp_cfg_extts()
1692 * @pf: Board private structure
1694 static void ice_ptp_disable_all_extts(struct ice_pf *pf) in ice_ptp_disable_all_extts() argument
1696 for (unsigned int i = 0; i < pf->ptp.info.n_ext_ts ; i++) in ice_ptp_disable_all_extts()
1697 if (pf->ptp.extts_rqs[i].flags & PTP_ENABLE_FEATURE) in ice_ptp_disable_all_extts()
1698 ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[i], in ice_ptp_disable_all_extts()
1701 synchronize_irq(pf->oicr_irq.virq); in ice_ptp_disable_all_extts()
1706 * @pf: Board private structure
1710 static void ice_ptp_enable_all_extts(struct ice_pf *pf) in ice_ptp_enable_all_extts() argument
1712 for (unsigned int i = 0; i < pf->ptp.info.n_ext_ts ; i++) in ice_ptp_enable_all_extts()
1713 if (pf->ptp.extts_rqs[i].flags & PTP_ENABLE_FEATURE) in ice_ptp_enable_all_extts()
1714 ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[i], in ice_ptp_enable_all_extts()
1788 * @pf: Board private structure
1797 static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq, in ice_ptp_cfg_perout() argument
1802 struct ice_hw *hw = &pf->hw; in ice_ptp_cfg_perout()
1808 pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT, rq->index); in ice_ptp_cfg_perout()
1812 gpio_pin = pf->ptp.ice_pin_desc[pin_desc_idx].gpio[1]; in ice_ptp_cfg_perout()
1813 prop_delay_ns = pf->ptp.ice_pin_desc[pin_desc_idx].delay[1]; in ice_ptp_cfg_perout()
1822 if (strncmp(pf->ptp.pin_desc[pin_desc_idx].name, "1PPS", 64) == 0 && in ice_ptp_cfg_perout()
1824 dev_err(ice_pf_to_dev(pf), "1PPS pin supports only 1 s period\n"); in ice_ptp_cfg_perout()
1829 dev_err(ice_pf_to_dev(pf), "CLK Period must be an even value\n"); in ice_ptp_cfg_perout()
1845 clk = ice_ptp_read_src_clk_reg(pf, NULL) + NSEC_PER_MSEC * 500; in ice_ptp_cfg_perout()
1857 * @pf: Board private structure
1863 static void ice_ptp_disable_all_perout(struct ice_pf *pf) in ice_ptp_disable_all_perout() argument
1865 for (unsigned int i = 0; i < pf->ptp.info.n_per_out; i++) in ice_ptp_disable_all_perout()
1866 if (pf->ptp.perout_rqs[i].period.sec || in ice_ptp_disable_all_perout()
1867 pf->ptp.perout_rqs[i].period.nsec) in ice_ptp_disable_all_perout()
1868 ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[i], in ice_ptp_disable_all_perout()
1874 * @pf: Board private structure
1880 static void ice_ptp_enable_all_perout(struct ice_pf *pf) in ice_ptp_enable_all_perout() argument
1882 for (unsigned int i = 0; i < pf->ptp.info.n_per_out; i++) in ice_ptp_enable_all_perout()
1883 if (pf->ptp.perout_rqs[i].period.sec || in ice_ptp_enable_all_perout()
1884 pf->ptp.perout_rqs[i].period.nsec) in ice_ptp_enable_all_perout()
1885 ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[i], in ice_ptp_enable_all_perout()
1891 * @pf: Board private structure
1897 static int ice_ptp_disable_shared_pin(struct ice_pf *pf, unsigned int pin, in ice_ptp_disable_shared_pin() argument
1904 gpio_pin = pf->ptp.ice_pin_desc[pin].gpio[1]; in ice_ptp_disable_shared_pin()
1907 gpio_pin = pf->ptp.ice_pin_desc[pin].gpio[0]; in ice_ptp_disable_shared_pin()
1913 for (unsigned int i = 0; i < pf->ptp.info.n_pins; i++) { in ice_ptp_disable_shared_pin()
1914 struct ptp_pin_desc *pin_desc = &pf->ptp.pin_desc[i]; in ice_ptp_disable_shared_pin()
1922 pf->ptp.ice_pin_desc[i].gpio[1] == gpio_pin) { in ice_ptp_disable_shared_pin()
1923 pf->ptp.perout_rqs[chan].period.sec = 0; in ice_ptp_disable_shared_pin()
1924 pf->ptp.perout_rqs[chan].period.nsec = 0; in ice_ptp_disable_shared_pin()
1927 dev_dbg(ice_pf_to_dev(pf), "Disabling pin %u with shared output GPIO pin %u\n", in ice_ptp_disable_shared_pin()
1929 return ice_ptp_cfg_perout(pf, &pf->ptp.perout_rqs[chan], in ice_ptp_disable_shared_pin()
1931 } else if (pf->ptp.pin_desc->func == PTP_PF_EXTTS && in ice_ptp_disable_shared_pin()
1932 pf->ptp.ice_pin_desc[i].gpio[0] == gpio_pin) { in ice_ptp_disable_shared_pin()
1933 pf->ptp.extts_rqs[chan].flags &= ~PTP_ENABLE_FEATURE; in ice_ptp_disable_shared_pin()
1936 dev_dbg(ice_pf_to_dev(pf), "Disabling pin %u with shared input GPIO pin %u\n", in ice_ptp_disable_shared_pin()
1938 return ice_ptp_cfg_extts(pf, &pf->ptp.extts_rqs[chan], in ice_ptp_disable_shared_pin()
1958 struct ice_pf *pf = ptp_info_to_pf(info); in ice_verify_pin() local
1961 pin_desc = &pf->ptp.ice_pin_desc[pin]; in ice_verify_pin()
1981 if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { in ice_verify_pin()
1982 ice_ptp_disable_shared_pin(pf, pin, func); in ice_verify_pin()
1983 pf->ptp.pin_desc[pin].func = func; in ice_verify_pin()
1984 pf->ptp.pin_desc[pin].chan = chan; in ice_verify_pin()
1985 return ice_ptp_set_sma_cfg(pf); in ice_verify_pin()
2002 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_gpio_enable() local
2009 &pf->ptp.perout_rqs[rq->perout.index]; in ice_ptp_gpio_enable()
2011 err = ice_ptp_cfg_perout(pf, &rq->perout, on); in ice_ptp_gpio_enable()
2023 &pf->ptp.extts_rqs[rq->extts.index]; in ice_ptp_gpio_enable()
2025 err = ice_ptp_cfg_extts(pf, &rq->extts, on); in ice_ptp_gpio_enable()
2051 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_gettimex64() local
2054 time_ns = ice_ptp_read_src_clk_reg(pf, sts); in ice_ptp_gettimex64()
2070 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_settime64() local
2072 struct ice_hw *hw = &pf->hw; in ice_ptp_settime64()
2081 dev_warn(ice_pf_to_dev(pf), "Failed to mark timestamps as invalid before settime\n"); in ice_ptp_settime64()
2090 ice_ptp_disable_all_perout(pf); in ice_ptp_settime64()
2092 err = ice_ptp_write_init(pf, &ts64); in ice_ptp_settime64()
2096 ice_ptp_reset_cached_phctime(pf); in ice_ptp_settime64()
2099 ice_ptp_enable_all_perout(pf); in ice_ptp_settime64()
2103 ice_ptp_restart_all_phy(pf); in ice_ptp_settime64()
2106 dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err); in ice_ptp_settime64()
2139 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_adjtime() local
2140 struct ice_hw *hw = &pf->hw; in ice_ptp_adjtime()
2144 dev = ice_pf_to_dev(pf); in ice_ptp_adjtime()
2161 ice_ptp_disable_all_perout(pf); in ice_ptp_adjtime()
2163 err = ice_ptp_write_adj(pf, delta); in ice_ptp_adjtime()
2166 ice_ptp_enable_all_perout(pf); in ice_ptp_adjtime()
2175 ice_ptp_reset_cached_phctime(pf); in ice_ptp_adjtime()
2238 * @pf: pointer to the PF private structure
2243 struct ice_pf *pf; member
2265 struct ice_pf *pf; in ice_capture_crosststamp() local
2271 pf = ctx->pf; in ice_capture_crosststamp()
2272 hw = &pf->hw; in ice_capture_crosststamp()
2283 dev_err(ice_pf_to_dev(pf), "PTP failed to get cross timestamp lock\n"); in ice_capture_crosststamp()
2346 struct ice_pf *pf = ptp_info_to_pf(info); in ice_ptp_getcrosststamp() local
2348 .pf = pf, in ice_ptp_getcrosststamp()
2351 switch (pf->hw.mac_type) { in ice_ptp_getcrosststamp()
2371 * @pf: Board private structure
2376 int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr) in ice_ptp_get_ts_config() argument
2380 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_get_ts_config()
2383 config = &pf->ptp.tstamp_config; in ice_ptp_get_ts_config()
2391 * @pf: Board private structure
2395 ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config) in ice_ptp_set_timestamp_mode() argument
2399 pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF; in ice_ptp_set_timestamp_mode()
2402 pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON; in ice_ptp_set_timestamp_mode()
2410 pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; in ice_ptp_set_timestamp_mode()
2426 pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL; in ice_ptp_set_timestamp_mode()
2433 ice_ptp_restore_timestamp_mode(pf); in ice_ptp_set_timestamp_mode()
2440 * @pf: Board private structure
2445 int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr) in ice_ptp_set_ts_config() argument
2450 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_set_ts_config()
2456 err = ice_ptp_set_timestamp_mode(pf, &config); in ice_ptp_set_ts_config()
2461 config = pf->ptp.tstamp_config; in ice_ptp_set_ts_config()
2490 * PHC value, rather than accessing the PF. This also allows us to in ice_ptp_get_rx_hwts()
2503 * @pf: Board private structure
2505 static void ice_ptp_setup_pin_cfg(struct ice_pf *pf) in ice_ptp_setup_pin_cfg() argument
2507 for (unsigned int i = 0; i < pf->ptp.info.n_pins; i++) { in ice_ptp_setup_pin_cfg()
2508 const struct ice_ptp_pin_desc *desc = &pf->ptp.ice_pin_desc[i]; in ice_ptp_setup_pin_cfg()
2509 struct ptp_pin_desc *pin = &pf->ptp.pin_desc[i]; in ice_ptp_setup_pin_cfg()
2512 if (!ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) in ice_ptp_setup_pin_cfg()
2522 pf->ptp.info.pin_config = pf->ptp.pin_desc; in ice_ptp_setup_pin_cfg()
2527 * @pf: pointer to the PF structure
2532 static void ice_ptp_disable_pins(struct ice_pf *pf) in ice_ptp_disable_pins() argument
2534 struct ptp_clock_info *info = &pf->ptp.info; in ice_ptp_disable_pins()
2536 dev_warn(ice_pf_to_dev(pf), "Failed to configure PTP pin control\n"); in ice_ptp_disable_pins()
2547 * @pf: pointer to the PF structure
2554 static int ice_ptp_parse_sdp_entries(struct ice_pf *pf, __le16 *entries, in ice_ptp_parse_sdp_entries() argument
2596 strscpy(pf->ptp.pin_desc[idx].name, in ice_ptp_parse_sdp_entries()
2598 sizeof(pf->ptp.pin_desc[idx] in ice_ptp_parse_sdp_entries()
2608 dev_dbg(ice_pf_to_dev(pf), in ice_ptp_parse_sdp_entries()
2613 pf->ptp.info.n_pins = n_pins; in ice_ptp_parse_sdp_entries()
2619 * @pf: Board private structure
2626 static void ice_ptp_set_funcs_e82x(struct ice_pf *pf) in ice_ptp_set_funcs_e82x() argument
2628 pf->ptp.info.getcrosststamp = ice_ptp_getcrosststamp; in ice_ptp_set_funcs_e82x()
2630 if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) { in ice_ptp_set_funcs_e82x()
2631 pf->ptp.ice_pin_desc = ice_pin_desc_e825c; in ice_ptp_set_funcs_e82x()
2632 pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e825c); in ice_ptp_set_funcs_e82x()
2634 pf->ptp.ice_pin_desc = ice_pin_desc_e82x; in ice_ptp_set_funcs_e82x()
2635 pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e82x); in ice_ptp_set_funcs_e82x()
2637 ice_ptp_setup_pin_cfg(pf); in ice_ptp_set_funcs_e82x()
2642 * @pf: Board private structure
2649 static void ice_ptp_set_funcs_e810(struct ice_pf *pf) in ice_ptp_set_funcs_e810() argument
2653 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_set_funcs_e810()
2657 err = ice_ptp_read_sdp_ac(&pf->hw, entries, &num_entries); in ice_ptp_set_funcs_e810()
2660 if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { in ice_ptp_set_funcs_e810()
2665 pf->ptp.ice_pin_desc = ice_pin_desc_e810; in ice_ptp_set_funcs_e810()
2666 pf->ptp.info.n_pins = in ice_ptp_set_funcs_e810()
2671 desc = devm_kcalloc(ice_pf_to_dev(pf), ICE_N_PINS_MAX, in ice_ptp_set_funcs_e810()
2677 err = ice_ptp_parse_sdp_entries(pf, entries, num_entries, desc); in ice_ptp_set_funcs_e810()
2685 ice_ptp_setup_pin_cfg(pf); in ice_ptp_set_funcs_e810()
2687 if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) in ice_ptp_set_funcs_e810()
2688 err = ice_ptp_set_sma_cfg(pf); in ice_ptp_set_funcs_e810()
2691 devm_kfree(ice_pf_to_dev(pf), desc); in ice_ptp_set_funcs_e810()
2692 ice_ptp_disable_pins(pf); in ice_ptp_set_funcs_e810()
2698 * @pf: Board private structure
2705 static void ice_ptp_set_funcs_e830(struct ice_pf *pf) in ice_ptp_set_funcs_e830() argument
2708 if (pcie_ptm_enabled(pf->pdev) && boot_cpu_has(X86_FEATURE_ART)) in ice_ptp_set_funcs_e830()
2709 pf->ptp.info.getcrosststamp = ice_ptp_getcrosststamp; in ice_ptp_set_funcs_e830()
2713 pf->ptp.ice_pin_desc = ice_pin_desc_e810; in ice_ptp_set_funcs_e830()
2714 pf->ptp.info.n_pins = ICE_PIN_DESC_ARR_LEN(ice_pin_desc_e810); in ice_ptp_set_funcs_e830()
2715 ice_ptp_setup_pin_cfg(pf); in ice_ptp_set_funcs_e830()
2720 * @pf: Board private structure
2722 static void ice_ptp_set_caps(struct ice_pf *pf) in ice_ptp_set_caps() argument
2724 struct ptp_clock_info *info = &pf->ptp.info; in ice_ptp_set_caps()
2725 struct device *dev = ice_pf_to_dev(pf); in ice_ptp_set_caps()
2740 switch (pf->hw.mac_type) { in ice_ptp_set_caps()
2742 ice_ptp_set_funcs_e810(pf); in ice_ptp_set_caps()
2745 ice_ptp_set_funcs_e830(pf); in ice_ptp_set_caps()
2749 ice_ptp_set_funcs_e82x(pf); in ice_ptp_set_caps()
2758 * @pf: Board private structure
2765 static long ice_ptp_create_clock(struct ice_pf *pf) in ice_ptp_create_clock() argument
2771 if (pf->ptp.clock) in ice_ptp_create_clock()
2774 ice_ptp_set_caps(pf); in ice_ptp_create_clock()
2776 info = &pf->ptp.info; in ice_ptp_create_clock()
2777 dev = ice_pf_to_dev(pf); in ice_ptp_create_clock()
2780 pf->ptp.clock = ptp_clock_register(info, dev); in ice_ptp_create_clock()
2781 if (IS_ERR(pf->ptp.clock)) { in ice_ptp_create_clock()
2782 dev_err(ice_pf_to_dev(pf), "Failed to register PTP clock device"); in ice_ptp_create_clock()
2783 return PTR_ERR(pf->ptp.clock); in ice_ptp_create_clock()
2839 * @pf: Board private structure
2844 enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf) in ice_ptp_process_ts() argument
2846 switch (pf->ptp.tx_interrupt_mode) { in ice_ptp_process_ts()
2852 return ice_ptp_tx_tstamp(&pf->ptp.port.tx); in ice_ptp_process_ts()
2855 return ice_ptp_tx_tstamp_owner(pf); in ice_ptp_process_ts()
2858 pf->ptp.tx_interrupt_mode); in ice_ptp_process_ts()
2865 * @pf: Board private structure
2870 irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf) in ice_ptp_ts_irq() argument
2872 struct ice_hw *hw = &pf->hw; in ice_ptp_ts_irq()
2881 struct ice_ptp_tx *tx = &pf->ptp.port.tx; in ice_ptp_ts_irq()
2884 if (!ice_pf_state_is_nominal(pf)) in ice_ptp_ts_irq()
2902 if (!ice_ptp_pf_handles_tx_interrupt(pf)) in ice_ptp_ts_irq()
2905 set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread); in ice_ptp_ts_irq()
2909 if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) { in ice_ptp_ts_irq()
2924 * @pf: Board private structure
2935 static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf) in ice_ptp_maybe_trigger_tx_interrupt() argument
2937 struct device *dev = ice_pf_to_dev(pf); in ice_ptp_maybe_trigger_tx_interrupt()
2938 struct ice_hw *hw = &pf->hw; in ice_ptp_maybe_trigger_tx_interrupt()
2942 if (!pf->ptp.port.tx.has_ready_bitmap) in ice_ptp_maybe_trigger_tx_interrupt()
2945 if (!ice_pf_src_tmr_owned(pf)) in ice_ptp_maybe_trigger_tx_interrupt()
2952 err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); in ice_ptp_maybe_trigger_tx_interrupt()
2973 struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp); in ice_ptp_periodic_work() local
2976 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_periodic_work()
2979 err = ice_ptp_update_cached_phctime(pf); in ice_ptp_periodic_work()
2981 ice_ptp_maybe_trigger_tx_interrupt(pf); in ice_ptp_periodic_work()
2990 * @pf: Board private structure
2993 void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) in ice_ptp_prepare_for_reset() argument
2995 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_prepare_for_reset()
3004 ice_ptp_disable_timestamp_mode(pf); in ice_ptp_prepare_for_reset()
3011 ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx); in ice_ptp_prepare_for_reset()
3014 ice_ptp_disable_all_perout(pf); in ice_ptp_prepare_for_reset()
3016 src_tmr = ice_get_ptp_src_clock_index(&pf->hw); in ice_ptp_prepare_for_reset()
3019 wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M); in ice_ptp_prepare_for_reset()
3027 * @pf: Board private structure
3032 static int ice_ptp_rebuild_owner(struct ice_pf *pf) in ice_ptp_rebuild_owner() argument
3034 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_rebuild_owner()
3035 struct ice_hw *hw = &pf->hw; in ice_ptp_rebuild_owner()
3051 err = ice_ptp_write_incval(hw, ice_base_incval(pf)); in ice_ptp_rebuild_owner()
3065 err = ice_ptp_write_init(pf, &ts); in ice_ptp_rebuild_owner()
3075 ice_ptp_flush_all_tx_tracker(pf); in ice_ptp_rebuild_owner()
3078 err = ice_ptp_cfg_phy_interrupt(pf, true, 1); in ice_ptp_rebuild_owner()
3082 ice_ptp_restart_all_phy(pf); in ice_ptp_rebuild_owner()
3085 ice_ptp_enable_all_perout(pf); in ice_ptp_rebuild_owner()
3086 ice_ptp_enable_all_extts(pf); in ice_ptp_rebuild_owner()
3097 * @pf: Board private structure
3100 void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) in ice_ptp_rebuild() argument
3102 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_rebuild()
3106 ice_ptp_prepare_for_reset(pf, reset_type); in ice_ptp_rebuild()
3109 dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n"); in ice_ptp_rebuild()
3113 if (ice_pf_src_tmr_owned(pf) && reset_type != ICE_RESET_PFR) { in ice_ptp_rebuild()
3114 err = ice_ptp_rebuild_owner(pf); in ice_ptp_rebuild()
3124 dev_info(ice_pf_to_dev(pf), "PTP reset successful\n"); in ice_ptp_rebuild()
3129 dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err); in ice_ptp_rebuild()
3139 static int ice_ptp_setup_adapter(struct ice_pf *pf) in ice_ptp_setup_adapter() argument
3141 if (!ice_pf_src_tmr_owned(pf) || !ice_is_primary(&pf->hw)) in ice_ptp_setup_adapter()
3144 pf->adapter->ctrl_pf = pf; in ice_ptp_setup_adapter()
3149 static int ice_ptp_setup_pf(struct ice_pf *pf) in ice_ptp_setup_pf() argument
3151 struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf); in ice_ptp_setup_pf()
3152 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_setup_pf()
3154 if (WARN_ON(!ctrl_ptp) || pf->hw.mac_type == ICE_MAC_UNKNOWN) in ice_ptp_setup_pf()
3158 mutex_lock(&pf->adapter->ports.lock); in ice_ptp_setup_pf()
3161 &pf->adapter->ports.ports); in ice_ptp_setup_pf()
3162 mutex_unlock(&pf->adapter->ports.lock); in ice_ptp_setup_pf()
3167 static void ice_ptp_cleanup_pf(struct ice_pf *pf) in ice_ptp_cleanup_pf() argument
3169 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_cleanup_pf()
3171 if (pf->hw.mac_type != ICE_MAC_UNKNOWN) { in ice_ptp_cleanup_pf()
3172 mutex_lock(&pf->adapter->ports.lock); in ice_ptp_cleanup_pf()
3174 mutex_unlock(&pf->adapter->ports.lock); in ice_ptp_cleanup_pf()
3180 * @pf: Board private structure
3182 * Returns: the PTP clock index associated with this PF, or -1 if no PTP clock
3185 int ice_ptp_clock_index(struct ice_pf *pf) in ice_ptp_clock_index() argument
3187 struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf); in ice_ptp_clock_index()
3199 * @pf: Board private structure
3205 static int ice_ptp_init_owner(struct ice_pf *pf) in ice_ptp_init_owner() argument
3207 struct ice_hw *hw = &pf->hw; in ice_ptp_init_owner()
3213 dev_err(ice_pf_to_dev(pf), "Failed to initialize PHC, err %d\n", in ice_ptp_init_owner()
3225 err = ice_ptp_write_incval(hw, ice_base_incval(pf)); in ice_ptp_init_owner()
3231 err = ice_ptp_write_init(pf, &ts); in ice_ptp_init_owner()
3239 err = ice_ptp_cfg_phy_interrupt(pf, true, 1); in ice_ptp_init_owner()
3244 err = ice_ptp_create_clock(pf); in ice_ptp_init_owner()
3250 pf->ptp.clock = NULL; in ice_ptp_init_owner()
3261 * @pf: Board private structure
3262 * @ptp: PF PTP structure
3264 static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp) in ice_ptp_init_work() argument
3275 dev_name(ice_pf_to_dev(pf))); in ice_ptp_init_work()
3289 * @pf: Board private structure
3294 static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port) in ice_ptp_init_port() argument
3296 struct ice_hw *hw = &pf->hw; in ice_ptp_init_port()
3304 return ice_ptp_init_tx(pf, &ptp_port->tx, ptp_port->port_num); in ice_ptp_init_port()
3308 return ice_ptp_init_tx_e82x(pf, &ptp_port->tx, in ice_ptp_init_port()
3317 * @pf: Board private structure
3320 * types, each PF processes the interrupt and manages its own timestamps. For
3324 static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf) in ice_ptp_init_tx_interrupt_mode() argument
3326 switch (pf->hw.mac_type) { in ice_ptp_init_tx_interrupt_mode()
3331 if (ice_pf_src_tmr_owned(pf)) in ice_ptp_init_tx_interrupt_mode()
3332 pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL; in ice_ptp_init_tx_interrupt_mode()
3334 pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_NONE; in ice_ptp_init_tx_interrupt_mode()
3338 pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_SELF; in ice_ptp_init_tx_interrupt_mode()
3344 * @pf: Board private structure
3354 void ice_ptp_init(struct ice_pf *pf) in ice_ptp_init() argument
3356 struct ice_ptp *ptp = &pf->ptp; in ice_ptp_init()
3357 struct ice_hw *hw = &pf->hw; in ice_ptp_init()
3371 ice_ptp_init_tx_interrupt_mode(pf); in ice_ptp_init()
3376 if (ice_pf_src_tmr_owned(pf) && ice_is_primary(hw)) { in ice_ptp_init()
3377 err = ice_ptp_setup_adapter(pf); in ice_ptp_init()
3380 err = ice_ptp_init_owner(pf); in ice_ptp_init()
3385 err = ice_ptp_setup_pf(pf); in ice_ptp_init()
3389 err = ice_ptp_init_port(pf, &ptp->port); in ice_ptp_init()
3394 ice_ptp_reset_phy_timestamping(pf); in ice_ptp_init()
3397 ice_ptp_cfg_tx_interrupt(pf); in ice_ptp_init()
3401 err = ice_ptp_init_work(pf, ptp); in ice_ptp_init()
3405 dev_info(ice_pf_to_dev(pf), "PTP init successful\n"); in ice_ptp_init()
3410 if (pf->ptp.clock) { in ice_ptp_init()
3412 pf->ptp.clock = NULL; in ice_ptp_init()
3415 dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err); in ice_ptp_init()
3420 * @pf: Board private structure
3425 void ice_ptp_release(struct ice_pf *pf) in ice_ptp_release() argument
3427 if (pf->ptp.state != ICE_PTP_READY) in ice_ptp_release()
3430 pf->ptp.state = ICE_PTP_UNINIT; in ice_ptp_release()
3433 ice_ptp_disable_timestamp_mode(pf); in ice_ptp_release()
3435 ice_ptp_cleanup_pf(pf); in ice_ptp_release()
3437 ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx); in ice_ptp_release()
3439 ice_ptp_disable_all_extts(pf); in ice_ptp_release()
3441 kthread_cancel_delayed_work_sync(&pf->ptp.work); in ice_ptp_release()
3443 ice_ptp_port_phy_stop(&pf->ptp.port); in ice_ptp_release()
3444 mutex_destroy(&pf->ptp.port.ps_lock); in ice_ptp_release()
3445 if (pf->ptp.kworker) { in ice_ptp_release()
3446 kthread_destroy_worker(pf->ptp.kworker); in ice_ptp_release()
3447 pf->ptp.kworker = NULL; in ice_ptp_release()
3450 if (!pf->ptp.clock) in ice_ptp_release()
3454 ice_ptp_disable_all_perout(pf); in ice_ptp_release()
3456 ptp_clock_unregister(pf->ptp.clock); in ice_ptp_release()
3457 pf->ptp.clock = NULL; in ice_ptp_release()
3459 dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n"); in ice_ptp_release()