1/* 10G controller driver for Samsung SoCs 2 * 3 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com 5 * 6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12#include <linux/bitops.h> 13#include <linux/kernel.h> 14#include <linux/netdevice.h> 15#include <linux/phy.h> 16#include "sxgbe_common.h" 17#include "sxgbe_xpcs.h" 18 19static int sxgbe_xpcs_read(struct net_device *ndev, unsigned int reg) 20{ 21 u32 value; 22 struct sxgbe_priv_data *priv = netdev_priv(ndev); 23 24 value = readl(priv->ioaddr + XPCS_OFFSET + reg); 25 26 return value; 27} 28 29static int sxgbe_xpcs_write(struct net_device *ndev, int reg, int data) 30{ 31 struct sxgbe_priv_data *priv = netdev_priv(ndev); 32 33 writel(data, priv->ioaddr + XPCS_OFFSET + reg); 34 35 return 0; 36} 37 38int sxgbe_xpcs_init(struct net_device *ndev) 39{ 40 u32 value; 41 42 value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1); 43 /* 10G XAUI mode */ 44 sxgbe_xpcs_write(ndev, SR_PCS_CONTROL2, XPCS_TYPE_SEL_X); 45 sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, XPCS_XAUI_MODE); 46 sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, value | BIT(13)); 47 sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value | BIT(11)); 48 49 do { 50 value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS); 51 } while ((value & XPCS_QSEQ_STATE_MPLLOFF) == XPCS_QSEQ_STATE_STABLE); 52 53 value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1); 54 sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(11)); 55 56 do { 57 value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS); 58 } while ((value & XPCS_QSEQ_STATE_MPLLOFF) != XPCS_QSEQ_STATE_STABLE); 59 60 return 0; 61} 62 63int sxgbe_xpcs_init_1G(struct net_device *ndev) 64{ 65 int value; 66 67 /* 10GBASE-X PCS (1G) mode */ 68 sxgbe_xpcs_write(ndev, SR_PCS_CONTROL2, XPCS_TYPE_SEL_X); 69 sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, XPCS_XAUI_MODE); 70 value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1); 71 sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(13)); 72 73 value = sxgbe_xpcs_read(ndev, SR_MII_MMD_CONTROL); 74 sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value | BIT(6)); 75 sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value & ~BIT(13)); 76 value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1); 77 sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value | BIT(11)); 78 79 do { 80 value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS); 81 } while ((value & XPCS_QSEQ_STATE_MPLLOFF) != XPCS_QSEQ_STATE_STABLE); 82 83 value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1); 84 sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(11)); 85 86 /* Auto Negotiation cluase 37 enable */ 87 value = sxgbe_xpcs_read(ndev, SR_MII_MMD_CONTROL); 88 sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value | BIT(12)); 89 90 return 0; 91} 92