diff options
Diffstat (limited to 'drivers/net/phy/dp83640.c')
| -rw-r--r-- | drivers/net/phy/dp83640.c | 217 | 
1 files changed, 113 insertions, 104 deletions
| diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 8f241b57fcf6..ac72a324fcd1 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -98,6 +98,7 @@ struct dp83640_private {  	struct list_head list;  	struct dp83640_clock *clock;  	struct phy_device *phydev; +	struct mii_timestamper mii_ts;  	struct delayed_work ts_work;  	int hwts_tx_en;  	int hwts_rx_en; @@ -1131,96 +1132,6 @@ static void dp83640_clock_put(struct dp83640_clock *clock)  	mutex_unlock(&clock->clock_lock);  } -static int dp83640_probe(struct phy_device *phydev) -{ -	struct dp83640_clock *clock; -	struct dp83640_private *dp83640; -	int err = -ENOMEM, i; - -	if (phydev->mdio.addr == BROADCAST_ADDR) -		return 0; - -	clock = dp83640_clock_get_bus(phydev->mdio.bus); -	if (!clock) -		goto no_clock; - -	dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); -	if (!dp83640) -		goto no_memory; - -	dp83640->phydev = phydev; -	INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); - -	INIT_LIST_HEAD(&dp83640->rxts); -	INIT_LIST_HEAD(&dp83640->rxpool); -	for (i = 0; i < MAX_RXTS; i++) -		list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); - -	phydev->priv = dp83640; - -	spin_lock_init(&dp83640->rx_lock); -	skb_queue_head_init(&dp83640->rx_queue); -	skb_queue_head_init(&dp83640->tx_queue); - -	dp83640->clock = clock; - -	if (choose_this_phy(clock, phydev)) { -		clock->chosen = dp83640; -		clock->ptp_clock = ptp_clock_register(&clock->caps, -						      &phydev->mdio.dev); -		if (IS_ERR(clock->ptp_clock)) { -			err = PTR_ERR(clock->ptp_clock); -			goto no_register; -		} -	} else -		list_add_tail(&dp83640->list, &clock->phylist); - -	dp83640_clock_put(clock); -	return 0; - -no_register: -	clock->chosen = NULL; -	kfree(dp83640); -no_memory: -	dp83640_clock_put(clock); -no_clock: -	return err; -} - -static void dp83640_remove(struct phy_device *phydev) -{ -	struct dp83640_clock *clock; -	struct list_head *this, *next; -	struct dp83640_private *tmp, *dp83640 = phydev->priv; - -	if (phydev->mdio.addr == BROADCAST_ADDR) -		return; - -	enable_status_frames(phydev, false); -	cancel_delayed_work_sync(&dp83640->ts_work); - -	skb_queue_purge(&dp83640->rx_queue); -	skb_queue_purge(&dp83640->tx_queue); - -	clock = dp83640_clock_get(dp83640->clock); - -	if (dp83640 == clock->chosen) { -		ptp_clock_unregister(clock->ptp_clock); -		clock->chosen = NULL; -	} else { -		list_for_each_safe(this, next, &clock->phylist) { -			tmp = list_entry(this, struct dp83640_private, list); -			if (tmp == dp83640) { -				list_del_init(&tmp->list); -				break; -			} -		} -	} - -	dp83640_clock_put(clock); -	kfree(dp83640); -} -  static int dp83640_soft_reset(struct phy_device *phydev)  {  	int ret; @@ -1319,9 +1230,10 @@ static int dp83640_config_intr(struct phy_device *phydev)  	}  } -static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) +static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)  { -	struct dp83640_private *dp83640 = phydev->priv; +	struct dp83640_private *dp83640 = +		container_of(mii_ts, struct dp83640_private, mii_ts);  	struct hwtstamp_config cfg;  	u16 txcfg0, rxcfg0; @@ -1397,8 +1309,8 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)  	mutex_lock(&dp83640->clock->extreg_lock); -	ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); -	ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); +	ext_write(0, dp83640->phydev, PAGE5, PTP_TXCFG0, txcfg0); +	ext_write(0, dp83640->phydev, PAGE5, PTP_RXCFG0, rxcfg0);  	mutex_unlock(&dp83640->clock->extreg_lock); @@ -1428,10 +1340,11 @@ static void rx_timestamp_work(struct work_struct *work)  		schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);  } -static bool dp83640_rxtstamp(struct phy_device *phydev, +static bool dp83640_rxtstamp(struct mii_timestamper *mii_ts,  			     struct sk_buff *skb, int type)  { -	struct dp83640_private *dp83640 = phydev->priv; +	struct dp83640_private *dp83640 = +		container_of(mii_ts, struct dp83640_private, mii_ts);  	struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;  	struct list_head *this, *next;  	struct rxts *rxts; @@ -1477,11 +1390,12 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,  	return true;  } -static void dp83640_txtstamp(struct phy_device *phydev, +static void dp83640_txtstamp(struct mii_timestamper *mii_ts,  			     struct sk_buff *skb, int type)  {  	struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb; -	struct dp83640_private *dp83640 = phydev->priv; +	struct dp83640_private *dp83640 = +		container_of(mii_ts, struct dp83640_private, mii_ts);  	switch (dp83640->hwts_tx_en) { @@ -1504,9 +1418,11 @@ static void dp83640_txtstamp(struct phy_device *phydev,  	}  } -static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info) +static int dp83640_ts_info(struct mii_timestamper *mii_ts, +			   struct ethtool_ts_info *info)  { -	struct dp83640_private *dp83640 = dev->priv; +	struct dp83640_private *dp83640 = +		container_of(mii_ts, struct dp83640_private, mii_ts);  	info->so_timestamping =  		SOF_TIMESTAMPING_TX_HARDWARE | @@ -1526,6 +1442,103 @@ static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info)  	return 0;  } +static int dp83640_probe(struct phy_device *phydev) +{ +	struct dp83640_clock *clock; +	struct dp83640_private *dp83640; +	int err = -ENOMEM, i; + +	if (phydev->mdio.addr == BROADCAST_ADDR) +		return 0; + +	clock = dp83640_clock_get_bus(phydev->mdio.bus); +	if (!clock) +		goto no_clock; + +	dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); +	if (!dp83640) +		goto no_memory; + +	dp83640->phydev = phydev; +	dp83640->mii_ts.rxtstamp = dp83640_rxtstamp; +	dp83640->mii_ts.txtstamp = dp83640_txtstamp; +	dp83640->mii_ts.hwtstamp = dp83640_hwtstamp; +	dp83640->mii_ts.ts_info  = dp83640_ts_info; + +	INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); +	INIT_LIST_HEAD(&dp83640->rxts); +	INIT_LIST_HEAD(&dp83640->rxpool); +	for (i = 0; i < MAX_RXTS; i++) +		list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); + +	phydev->mii_ts = &dp83640->mii_ts; +	phydev->priv = dp83640; + +	spin_lock_init(&dp83640->rx_lock); +	skb_queue_head_init(&dp83640->rx_queue); +	skb_queue_head_init(&dp83640->tx_queue); + +	dp83640->clock = clock; + +	if (choose_this_phy(clock, phydev)) { +		clock->chosen = dp83640; +		clock->ptp_clock = ptp_clock_register(&clock->caps, +						      &phydev->mdio.dev); +		if (IS_ERR(clock->ptp_clock)) { +			err = PTR_ERR(clock->ptp_clock); +			goto no_register; +		} +	} else +		list_add_tail(&dp83640->list, &clock->phylist); + +	dp83640_clock_put(clock); +	return 0; + +no_register: +	clock->chosen = NULL; +	kfree(dp83640); +no_memory: +	dp83640_clock_put(clock); +no_clock: +	return err; +} + +static void dp83640_remove(struct phy_device *phydev) +{ +	struct dp83640_clock *clock; +	struct list_head *this, *next; +	struct dp83640_private *tmp, *dp83640 = phydev->priv; + +	if (phydev->mdio.addr == BROADCAST_ADDR) +		return; + +	phydev->mii_ts = NULL; + +	enable_status_frames(phydev, false); +	cancel_delayed_work_sync(&dp83640->ts_work); + +	skb_queue_purge(&dp83640->rx_queue); +	skb_queue_purge(&dp83640->tx_queue); + +	clock = dp83640_clock_get(dp83640->clock); + +	if (dp83640 == clock->chosen) { +		ptp_clock_unregister(clock->ptp_clock); +		clock->chosen = NULL; +	} else { +		list_for_each_safe(this, next, &clock->phylist) { +			tmp = list_entry(this, struct dp83640_private, list); +			if (tmp == dp83640) { +				list_del_init(&tmp->list); +				break; +			} +		} +	} + +	dp83640_clock_put(clock); +	kfree(dp83640); +} +  static struct phy_driver dp83640_driver = {  	.phy_id		= DP83640_PHY_ID,  	.phy_id_mask	= 0xfffffff0, @@ -1537,10 +1550,6 @@ static struct phy_driver dp83640_driver = {  	.config_init	= dp83640_config_init,  	.ack_interrupt  = dp83640_ack_interrupt,  	.config_intr    = dp83640_config_intr, -	.ts_info	= dp83640_ts_info, -	.hwtstamp	= dp83640_hwtstamp, -	.rxtstamp	= dp83640_rxtstamp, -	.txtstamp	= dp83640_txtstamp,  };  static int __init dp83640_init(void) | 
