bgmac.c (ead5d1f4d877e92c051e1a1ade623d0d30e71619) bgmac.c (12cf8e75727a76d6e617619b791ac0de062e7bdb)
1/*
2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
3 *
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
5 *
6 * Licensed under the GNU/GPL. See COPYING for details.
7 */
8

--- 732 unchanged lines hidden (view full) ---

741
742/**************************************************
743 * Chip ops
744 **************************************************/
745
746/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
747 * nothing to change? Try if after stabilizng driver.
748 */
1/*
2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
3 *
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
5 *
6 * Licensed under the GNU/GPL. See COPYING for details.
7 */
8

--- 732 unchanged lines hidden (view full) ---

741
742/**************************************************
743 * Chip ops
744 **************************************************/
745
746/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
747 * nothing to change? Try if after stabilizng driver.
748 */
749static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
750 bool force)
749static void bgmac_umac_cmd_maskset(struct bgmac *bgmac, u32 mask, u32 set,
750 bool force)
751{
751{
752 u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
752 u32 cmdcfg = bgmac_umac_read(bgmac, BGMAC_CMDCFG);
753 u32 new_val = (cmdcfg & mask) | set;
754 u32 cmdcfg_sr;
755
756 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
757 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
758 else
759 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
760
753 u32 new_val = (cmdcfg & mask) | set;
754 u32 cmdcfg_sr;
755
756 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
757 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
758 else
759 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
760
761 bgmac_set(bgmac, BGMAC_CMDCFG, cmdcfg_sr);
761 bgmac_umac_maskset(bgmac, BGMAC_CMDCFG, ~0, cmdcfg_sr);
762 udelay(2);
763
764 if (new_val != cmdcfg || force)
762 udelay(2);
763
764 if (new_val != cmdcfg || force)
765 bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
765 bgmac_umac_write(bgmac, BGMAC_CMDCFG, new_val);
766
766
767 bgmac_mask(bgmac, BGMAC_CMDCFG, ~cmdcfg_sr);
767 bgmac_umac_maskset(bgmac, BGMAC_CMDCFG, ~cmdcfg_sr, 0);
768 udelay(2);
769}
770
771static void bgmac_write_mac_address(struct bgmac *bgmac, u8 *addr)
772{
773 u32 tmp;
774
775 tmp = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
768 udelay(2);
769}
770
771static void bgmac_write_mac_address(struct bgmac *bgmac, u8 *addr)
772{
773 u32 tmp;
774
775 tmp = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
776 bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
776 bgmac_umac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
777 tmp = (addr[4] << 8) | addr[5];
777 tmp = (addr[4] << 8) | addr[5];
778 bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
778 bgmac_umac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
779}
780
781static void bgmac_set_rx_mode(struct net_device *net_dev)
782{
783 struct bgmac *bgmac = netdev_priv(net_dev);
784
785 if (net_dev->flags & IFF_PROMISC)
779}
780
781static void bgmac_set_rx_mode(struct net_device *net_dev)
782{
783 struct bgmac *bgmac = netdev_priv(net_dev);
784
785 if (net_dev->flags & IFF_PROMISC)
786 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, true);
786 bgmac_umac_cmd_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, true);
787 else
787 else
788 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, true);
788 bgmac_umac_cmd_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, true);
789}
790
791#if 0 /* We don't use that regs yet */
792static void bgmac_chip_stats_update(struct bgmac *bgmac)
793{
794 int i;
795
796 if (!(bgmac->feature_flags & BGMAC_FEAT_NO_CLR_MIB)) {

--- 47 unchanged lines hidden (view full) ---

844 default:
845 dev_err(bgmac->dev, "Unsupported speed: %d\n",
846 bgmac->mac_speed);
847 }
848
849 if (bgmac->mac_duplex == DUPLEX_HALF)
850 set |= BGMAC_CMDCFG_HD;
851
789}
790
791#if 0 /* We don't use that regs yet */
792static void bgmac_chip_stats_update(struct bgmac *bgmac)
793{
794 int i;
795
796 if (!(bgmac->feature_flags & BGMAC_FEAT_NO_CLR_MIB)) {

--- 47 unchanged lines hidden (view full) ---

844 default:
845 dev_err(bgmac->dev, "Unsupported speed: %d\n",
846 bgmac->mac_speed);
847 }
848
849 if (bgmac->mac_duplex == DUPLEX_HALF)
850 set |= BGMAC_CMDCFG_HD;
851
852 bgmac_cmdcfg_maskset(bgmac, mask, set, true);
852 bgmac_umac_cmd_maskset(bgmac, mask, set, true);
853}
854
855static void bgmac_miiconfig(struct bgmac *bgmac)
856{
857 if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) {
858 if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
859 bgmac_idm_write(bgmac, BCMA_IOCTL,
860 bgmac_idm_read(bgmac, BCMA_IOCTL) |

--- 51 unchanged lines hidden (view full) ---

912 if (!bgmac->stats_grabbed) {
913 /* bgmac_chip_stats_update(bgmac); */
914 bgmac->stats_grabbed = true;
915 }
916
917 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
918 bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
919
853}
854
855static void bgmac_miiconfig(struct bgmac *bgmac)
856{
857 if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) {
858 if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
859 bgmac_idm_write(bgmac, BCMA_IOCTL,
860 bgmac_idm_read(bgmac, BCMA_IOCTL) |

--- 51 unchanged lines hidden (view full) ---

912 if (!bgmac->stats_grabbed) {
913 /* bgmac_chip_stats_update(bgmac); */
914 bgmac->stats_grabbed = true;
915 }
916
917 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
918 bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
919
920 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
920 bgmac_umac_cmd_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
921 udelay(1);
922
923 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
924 bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
925
926 /* TODO: Clear software multicast filter list */
927 }
928

--- 61 unchanged lines hidden (view full) ---

990 * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
991 * be keps until taking MAC out of the reset.
992 */
993 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
994 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
995 else
996 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
997
921 udelay(1);
922
923 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
924 bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
925
926 /* TODO: Clear software multicast filter list */
927 }
928

--- 61 unchanged lines hidden (view full) ---

990 * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
991 * be keps until taking MAC out of the reset.
992 */
993 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
994 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
995 else
996 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
997
998 bgmac_cmdcfg_maskset(bgmac,
999 ~(BGMAC_CMDCFG_TE |
1000 BGMAC_CMDCFG_RE |
1001 BGMAC_CMDCFG_RPI |
1002 BGMAC_CMDCFG_TAI |
1003 BGMAC_CMDCFG_HD |
1004 BGMAC_CMDCFG_ML |
998 bgmac_umac_cmd_maskset(bgmac,
999 ~(BGMAC_CMDCFG_TE |
1000 BGMAC_CMDCFG_RE |
1001 BGMAC_CMDCFG_RPI |
1002 BGMAC_CMDCFG_TAI |
1003 BGMAC_CMDCFG_HD |
1004 BGMAC_CMDCFG_ML |
1005 BGMAC_CMDCFG_CFE |
1006 BGMAC_CMDCFG_RL |
1007 BGMAC_CMDCFG_RED |
1008 BGMAC_CMDCFG_PE |
1009 BGMAC_CMDCFG_TPI |
1010 BGMAC_CMDCFG_PAD_EN |
1011 BGMAC_CMDCFG_PF),
1012 BGMAC_CMDCFG_PROM |
1013 BGMAC_CMDCFG_NLC |
1005 BGMAC_CMDCFG_CFE |
1014 BGMAC_CMDCFG_CFE |
1006 BGMAC_CMDCFG_RL |
1007 BGMAC_CMDCFG_RED |
1008 BGMAC_CMDCFG_PE |
1009 BGMAC_CMDCFG_TPI |
1010 BGMAC_CMDCFG_PAD_EN |
1011 BGMAC_CMDCFG_PF),
1012 BGMAC_CMDCFG_PROM |
1013 BGMAC_CMDCFG_NLC |
1014 BGMAC_CMDCFG_CFE |
1015 cmdcfg_sr,
1016 false);
1015 cmdcfg_sr,
1016 false);
1017 bgmac->mac_speed = SPEED_UNKNOWN;
1018 bgmac->mac_duplex = DUPLEX_UNKNOWN;
1019
1020 bgmac_clear_mib(bgmac);
1021 if (bgmac->feature_flags & BGMAC_FEAT_CMN_PHY_CTL)
1022 bgmac_cmn_maskset32(bgmac, BCMA_GMAC_CMN_PHY_CTL, ~0,
1023 BCMA_GMAC_CMN_PC_MTE);
1024 else

--- 23 unchanged lines hidden (view full) ---

1048 u32 cmdcfg;
1049 u32 mode;
1050
1051 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
1052 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
1053 else
1054 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
1055
1017 bgmac->mac_speed = SPEED_UNKNOWN;
1018 bgmac->mac_duplex = DUPLEX_UNKNOWN;
1019
1020 bgmac_clear_mib(bgmac);
1021 if (bgmac->feature_flags & BGMAC_FEAT_CMN_PHY_CTL)
1022 bgmac_cmn_maskset32(bgmac, BCMA_GMAC_CMN_PHY_CTL, ~0,
1023 BCMA_GMAC_CMN_PC_MTE);
1024 else

--- 23 unchanged lines hidden (view full) ---

1048 u32 cmdcfg;
1049 u32 mode;
1050
1051 if (bgmac->feature_flags & BGMAC_FEAT_CMDCFG_SR_REV4)
1052 cmdcfg_sr = BGMAC_CMDCFG_SR_REV4;
1053 else
1054 cmdcfg_sr = BGMAC_CMDCFG_SR_REV0;
1055
1056 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
1057 bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
1058 cmdcfg_sr, true);
1056 cmdcfg = bgmac_umac_read(bgmac, BGMAC_CMDCFG);
1057 bgmac_umac_cmd_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
1058 cmdcfg_sr, true);
1059 udelay(2);
1060 cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
1059 udelay(2);
1060 cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
1061 bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
1061 bgmac_umac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
1062
1063 mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
1064 BGMAC_DS_MM_SHIFT;
1065 if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0)
1066 bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
1067 if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) && mode == 2)
1068 bgmac_cco_ctl_maskset(bgmac, 1, ~0,
1069 BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
1070
1071 if (bgmac->feature_flags & (BGMAC_FEAT_FLW_CTRL1 |
1072 BGMAC_FEAT_FLW_CTRL2)) {
1073 u32 fl_ctl;
1074
1075 if (bgmac->feature_flags & BGMAC_FEAT_FLW_CTRL1)
1076 fl_ctl = 0x2300e1;
1077 else
1078 fl_ctl = 0x03cb04cb;
1079
1080 bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
1062
1063 mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
1064 BGMAC_DS_MM_SHIFT;
1065 if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0)
1066 bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
1067 if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) && mode == 2)
1068 bgmac_cco_ctl_maskset(bgmac, 1, ~0,
1069 BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
1070
1071 if (bgmac->feature_flags & (BGMAC_FEAT_FLW_CTRL1 |
1072 BGMAC_FEAT_FLW_CTRL2)) {
1073 u32 fl_ctl;
1074
1075 if (bgmac->feature_flags & BGMAC_FEAT_FLW_CTRL1)
1076 fl_ctl = 0x2300e1;
1077 else
1078 fl_ctl = 0x03cb04cb;
1079
1080 bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
1081 bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
1081 bgmac_umac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
1082 }
1083
1084 if (bgmac->feature_flags & BGMAC_FEAT_SET_RXQ_CLK) {
1085 u32 rxq_ctl;
1086 u16 bp_clk;
1087 u8 mdp;
1088
1089 rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);

--- 10 unchanged lines hidden (view full) ---

1100{
1101 /* Clear any erroneously pending interrupts */
1102 bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
1103
1104 /* 1 interrupt per received frame */
1105 bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
1106
1107 /* Enable 802.3x tx flow control (honor received PAUSE frames) */
1082 }
1083
1084 if (bgmac->feature_flags & BGMAC_FEAT_SET_RXQ_CLK) {
1085 u32 rxq_ctl;
1086 u16 bp_clk;
1087 u8 mdp;
1088
1089 rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);

--- 10 unchanged lines hidden (view full) ---

1100{
1101 /* Clear any erroneously pending interrupts */
1102 bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
1103
1104 /* 1 interrupt per received frame */
1105 bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
1106
1107 /* Enable 802.3x tx flow control (honor received PAUSE frames) */
1108 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
1108 bgmac_umac_cmd_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
1109
1110 bgmac_set_rx_mode(bgmac->net_dev);
1111
1112 bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr);
1113
1114 if (bgmac->loopback)
1109
1110 bgmac_set_rx_mode(bgmac->net_dev);
1111
1112 bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr);
1113
1114 if (bgmac->loopback)
1115 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
1115 bgmac_umac_cmd_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
1116 else
1116 else
1117 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false);
1117 bgmac_umac_cmd_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false);
1118
1118
1119 bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
1119 bgmac_umac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
1120
1121 bgmac_chip_intrs_on(bgmac);
1122
1123 bgmac_enable(bgmac);
1124}
1125
1126static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1127{

--- 119 unchanged lines hidden (view full) ---

1247 eth_commit_mac_addr_change(net_dev, addr);
1248 return 0;
1249}
1250
1251static int bgmac_change_mtu(struct net_device *net_dev, int mtu)
1252{
1253 struct bgmac *bgmac = netdev_priv(net_dev);
1254
1120
1121 bgmac_chip_intrs_on(bgmac);
1122
1123 bgmac_enable(bgmac);
1124}
1125
1126static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1127{

--- 119 unchanged lines hidden (view full) ---

1247 eth_commit_mac_addr_change(net_dev, addr);
1248 return 0;
1249}
1250
1251static int bgmac_change_mtu(struct net_device *net_dev, int mtu)
1252{
1253 struct bgmac *bgmac = netdev_priv(net_dev);
1254
1255 bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + mtu);
1255 bgmac_umac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + mtu);
1256 return 0;
1257}
1258
1259static const struct net_device_ops bgmac_netdev_ops = {
1260 .ndo_open = bgmac_open,
1261 .ndo_stop = bgmac_stop,
1262 .ndo_start_xmit = bgmac_start_xmit,
1263 .ndo_set_rx_mode = bgmac_set_rx_mode,

--- 363 unchanged lines hidden ---
1256 return 0;
1257}
1258
1259static const struct net_device_ops bgmac_netdev_ops = {
1260 .ndo_open = bgmac_open,
1261 .ndo_stop = bgmac_stop,
1262 .ndo_start_xmit = bgmac_start_xmit,
1263 .ndo_set_rx_mode = bgmac_set_rx_mode,

--- 363 unchanged lines hidden ---