Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* $Date: 2006/04/28 19:20:06 $ $RCSfile: vsc7326.c,v $ $Revision: 1.19 $ */
0003 
0004 /* Driver for Vitesse VSC7326 (Schaumburg) MAC */
0005 
0006 #include "gmac.h"
0007 #include "elmer0.h"
0008 #include "vsc7326_reg.h"
0009 
0010 /* Update fast changing statistics every 15 seconds */
0011 #define STATS_TICK_SECS 15
0012 /* 30 minutes for full statistics update */
0013 #define MAJOR_UPDATE_TICKS (1800 / STATS_TICK_SECS)
0014 
0015 /* The egress WM value 0x01a01fff should be used only when the
0016  * interface is down (MAC port disabled). This is a workaround
0017  * for disabling the T2/MAC flow-control. When the interface is
0018  * enabled, the WM value should be set to 0x014a03F0.
0019  */
0020 #define WM_DISABLE  0x01a01fff
0021 #define WM_ENABLE   0x014a03F0
0022 
0023 struct init_table {
0024     u32 addr;
0025     u32 data;
0026 };
0027 
0028 struct _cmac_instance {
0029     u32 index;
0030     u32 ticks;
0031 };
0032 
0033 #define INITBLOCK_SLEEP 0xffffffff
0034 
0035 static void vsc_read(adapter_t *adapter, u32 addr, u32 *val)
0036 {
0037     u32 status, vlo, vhi;
0038     int i;
0039 
0040     spin_lock_bh(&adapter->mac_lock);
0041     t1_tpi_read(adapter, (addr << 2) + 4, &vlo);
0042     i = 0;
0043     do {
0044         t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
0045         t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
0046         status = (vhi << 16) | vlo;
0047         i++;
0048     } while (((status & 1) == 0) && (i < 50));
0049     if (i == 50)
0050         pr_err("Invalid tpi read from MAC, breaking loop.\n");
0051 
0052     t1_tpi_read(adapter, (REG_LOCAL_DATA << 2) + 4, &vlo);
0053     t1_tpi_read(adapter, REG_LOCAL_DATA << 2, &vhi);
0054 
0055     *val = (vhi << 16) | vlo;
0056 
0057     /* pr_err("rd: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
0058         ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
0059         ((addr&0x01fe)>>1), *val); */
0060     spin_unlock_bh(&adapter->mac_lock);
0061 }
0062 
0063 static void vsc_write(adapter_t *adapter, u32 addr, u32 data)
0064 {
0065     spin_lock_bh(&adapter->mac_lock);
0066     t1_tpi_write(adapter, (addr << 2) + 4, data & 0xFFFF);
0067     t1_tpi_write(adapter, addr << 2, (data >> 16) & 0xFFFF);
0068     /* pr_err("wr: block: 0x%x  sublock: 0x%x  reg: 0x%x  data: 0x%x\n",
0069         ((addr&0xe000)>>13), ((addr&0x1e00)>>9),
0070         ((addr&0x01fe)>>1), data); */
0071     spin_unlock_bh(&adapter->mac_lock);
0072 }
0073 
0074 /* Hard reset the MAC.  This wipes out *all* configuration. */
0075 static void vsc7326_full_reset(adapter_t* adapter)
0076 {
0077     u32 val;
0078     u32 result = 0xffff;
0079 
0080     t1_tpi_read(adapter, A_ELMER0_GPO, &val);
0081     val &= ~1;
0082     t1_tpi_write(adapter, A_ELMER0_GPO, val);
0083     udelay(2);
0084     val |= 0x1; /* Enable mac MAC itself */
0085     val |= 0x800;   /* Turn off the red LED */
0086     t1_tpi_write(adapter, A_ELMER0_GPO, val);
0087     mdelay(1);
0088     vsc_write(adapter, REG_SW_RESET, 0x80000001);
0089     do {
0090         mdelay(1);
0091         vsc_read(adapter, REG_SW_RESET, &result);
0092     } while (result != 0x0);
0093 }
0094 
0095 static struct init_table vsc7326_reset[] = {
0096     {      REG_IFACE_MODE, 0x00000000 },
0097     {         REG_CRC_CFG, 0x00000020 },
0098     {   REG_PLL_CLK_SPEED, 0x00050c00 },
0099     {   REG_PLL_CLK_SPEED, 0x00050c00 },
0100     {            REG_MSCH, 0x00002f14 },
0101     {       REG_SPI4_MISC, 0x00040409 },
0102     {     REG_SPI4_DESKEW, 0x00080000 },
0103     { REG_SPI4_ING_SETUP2, 0x08080004 },
0104     { REG_SPI4_ING_SETUP0, 0x04111004 },
0105     { REG_SPI4_EGR_SETUP0, 0x80001a04 },
0106     { REG_SPI4_ING_SETUP1, 0x02010000 },
0107     {      REG_AGE_INC(0), 0x00000000 },
0108     {      REG_AGE_INC(1), 0x00000000 },
0109     {     REG_ING_CONTROL, 0x0a200011 },
0110     {     REG_EGR_CONTROL, 0xa0010091 },
0111 };
0112 
0113 static struct init_table vsc7326_portinit[4][22] = {
0114     {   /* Port 0 */
0115             /* FIFO setup */
0116         {           REG_DBG(0), 0x000004f0 },
0117         {           REG_HDX(0), 0x00073101 },
0118         {        REG_TEST(0,0), 0x00000022 },
0119         {        REG_TEST(1,0), 0x00000022 },
0120         {  REG_TOP_BOTTOM(0,0), 0x003f0000 },
0121         {  REG_TOP_BOTTOM(1,0), 0x00120000 },
0122         { REG_HIGH_LOW_WM(0,0), 0x07460757 },
0123         { REG_HIGH_LOW_WM(1,0), WM_DISABLE },
0124         {   REG_CT_THRHLD(0,0), 0x00000000 },
0125         {   REG_CT_THRHLD(1,0), 0x00000000 },
0126         {         REG_BUCKE(0), 0x0002ffff },
0127         {         REG_BUCKI(0), 0x0002ffff },
0128         {        REG_TEST(0,0), 0x00000020 },
0129         {        REG_TEST(1,0), 0x00000020 },
0130             /* Port config */
0131         {       REG_MAX_LEN(0), 0x00002710 },
0132         {     REG_PORT_FAIL(0), 0x00000002 },
0133         {    REG_NORMALIZER(0), 0x00000a64 },
0134         {        REG_DENORM(0), 0x00000010 },
0135         {     REG_STICK_BIT(0), 0x03baa370 },
0136         {     REG_DEV_SETUP(0), 0x00000083 },
0137         {     REG_DEV_SETUP(0), 0x00000082 },
0138         {      REG_MODE_CFG(0), 0x0200259f },
0139     },
0140     {   /* Port 1 */
0141             /* FIFO setup */
0142         {           REG_DBG(1), 0x000004f0 },
0143         {           REG_HDX(1), 0x00073101 },
0144         {        REG_TEST(0,1), 0x00000022 },
0145         {        REG_TEST(1,1), 0x00000022 },
0146         {  REG_TOP_BOTTOM(0,1), 0x007e003f },
0147         {  REG_TOP_BOTTOM(1,1), 0x00240012 },
0148         { REG_HIGH_LOW_WM(0,1), 0x07460757 },
0149         { REG_HIGH_LOW_WM(1,1), WM_DISABLE },
0150         {   REG_CT_THRHLD(0,1), 0x00000000 },
0151         {   REG_CT_THRHLD(1,1), 0x00000000 },
0152         {         REG_BUCKE(1), 0x0002ffff },
0153         {         REG_BUCKI(1), 0x0002ffff },
0154         {        REG_TEST(0,1), 0x00000020 },
0155         {        REG_TEST(1,1), 0x00000020 },
0156             /* Port config */
0157         {       REG_MAX_LEN(1), 0x00002710 },
0158         {     REG_PORT_FAIL(1), 0x00000002 },
0159         {    REG_NORMALIZER(1), 0x00000a64 },
0160         {        REG_DENORM(1), 0x00000010 },
0161         {     REG_STICK_BIT(1), 0x03baa370 },
0162         {     REG_DEV_SETUP(1), 0x00000083 },
0163         {     REG_DEV_SETUP(1), 0x00000082 },
0164         {      REG_MODE_CFG(1), 0x0200259f },
0165     },
0166     {   /* Port 2 */
0167             /* FIFO setup */
0168         {           REG_DBG(2), 0x000004f0 },
0169         {           REG_HDX(2), 0x00073101 },
0170         {        REG_TEST(0,2), 0x00000022 },
0171         {        REG_TEST(1,2), 0x00000022 },
0172         {  REG_TOP_BOTTOM(0,2), 0x00bd007e },
0173         {  REG_TOP_BOTTOM(1,2), 0x00360024 },
0174         { REG_HIGH_LOW_WM(0,2), 0x07460757 },
0175         { REG_HIGH_LOW_WM(1,2), WM_DISABLE },
0176         {   REG_CT_THRHLD(0,2), 0x00000000 },
0177         {   REG_CT_THRHLD(1,2), 0x00000000 },
0178         {         REG_BUCKE(2), 0x0002ffff },
0179         {         REG_BUCKI(2), 0x0002ffff },
0180         {        REG_TEST(0,2), 0x00000020 },
0181         {        REG_TEST(1,2), 0x00000020 },
0182             /* Port config */
0183         {       REG_MAX_LEN(2), 0x00002710 },
0184         {     REG_PORT_FAIL(2), 0x00000002 },
0185         {    REG_NORMALIZER(2), 0x00000a64 },
0186         {        REG_DENORM(2), 0x00000010 },
0187         {     REG_STICK_BIT(2), 0x03baa370 },
0188         {     REG_DEV_SETUP(2), 0x00000083 },
0189         {     REG_DEV_SETUP(2), 0x00000082 },
0190         {      REG_MODE_CFG(2), 0x0200259f },
0191     },
0192     {   /* Port 3 */
0193             /* FIFO setup */
0194         {           REG_DBG(3), 0x000004f0 },
0195         {           REG_HDX(3), 0x00073101 },
0196         {        REG_TEST(0,3), 0x00000022 },
0197         {        REG_TEST(1,3), 0x00000022 },
0198         {  REG_TOP_BOTTOM(0,3), 0x00fc00bd },
0199         {  REG_TOP_BOTTOM(1,3), 0x00480036 },
0200         { REG_HIGH_LOW_WM(0,3), 0x07460757 },
0201         { REG_HIGH_LOW_WM(1,3), WM_DISABLE },
0202         {   REG_CT_THRHLD(0,3), 0x00000000 },
0203         {   REG_CT_THRHLD(1,3), 0x00000000 },
0204         {         REG_BUCKE(3), 0x0002ffff },
0205         {         REG_BUCKI(3), 0x0002ffff },
0206         {        REG_TEST(0,3), 0x00000020 },
0207         {        REG_TEST(1,3), 0x00000020 },
0208             /* Port config */
0209         {       REG_MAX_LEN(3), 0x00002710 },
0210         {     REG_PORT_FAIL(3), 0x00000002 },
0211         {    REG_NORMALIZER(3), 0x00000a64 },
0212         {        REG_DENORM(3), 0x00000010 },
0213         {     REG_STICK_BIT(3), 0x03baa370 },
0214         {     REG_DEV_SETUP(3), 0x00000083 },
0215         {     REG_DEV_SETUP(3), 0x00000082 },
0216         {      REG_MODE_CFG(3), 0x0200259f },
0217     },
0218 };
0219 
0220 static void run_table(adapter_t *adapter, struct init_table *ib, int len)
0221 {
0222     int i;
0223 
0224     for (i = 0; i < len; i++) {
0225         if (ib[i].addr == INITBLOCK_SLEEP) {
0226             udelay( ib[i].data );
0227             pr_err("sleep %d us\n",ib[i].data);
0228         } else
0229             vsc_write( adapter, ib[i].addr, ib[i].data );
0230     }
0231 }
0232 
0233 static int bist_rd(adapter_t *adapter, int moduleid, int address)
0234 {
0235     int data = 0;
0236     u32 result = 0;
0237 
0238     if ((address != 0x0) &&
0239         (address != 0x1) &&
0240         (address != 0x2) &&
0241         (address != 0xd) &&
0242         (address != 0xe))
0243             pr_err("No bist address: 0x%x\n", address);
0244 
0245     data = ((0x00 << 24) | ((address & 0xff) << 16) | (0x00 << 8) |
0246         ((moduleid & 0xff) << 0));
0247     vsc_write(adapter, REG_RAM_BIST_CMD, data);
0248 
0249     udelay(10);
0250 
0251     vsc_read(adapter, REG_RAM_BIST_RESULT, &result);
0252     if ((result & (1 << 9)) != 0x0)
0253         pr_err("Still in bist read: 0x%x\n", result);
0254     else if ((result & (1 << 8)) != 0x0)
0255         pr_err("bist read error: 0x%x\n", result);
0256 
0257     return result & 0xff;
0258 }
0259 
0260 static int bist_wr(adapter_t *adapter, int moduleid, int address, int value)
0261 {
0262     int data = 0;
0263     u32 result = 0;
0264 
0265     if ((address != 0x0) &&
0266         (address != 0x1) &&
0267         (address != 0x2) &&
0268         (address != 0xd) &&
0269         (address != 0xe))
0270             pr_err("No bist address: 0x%x\n", address);
0271 
0272     if (value > 255)
0273         pr_err("Suspicious write out of range value: 0x%x\n", value);
0274 
0275     data = ((0x01 << 24) | ((address & 0xff) << 16) | (value << 8) |
0276         ((moduleid & 0xff) << 0));
0277     vsc_write(adapter, REG_RAM_BIST_CMD, data);
0278 
0279     udelay(5);
0280 
0281     vsc_read(adapter, REG_RAM_BIST_CMD, &result);
0282     if ((result & (1 << 27)) != 0x0)
0283         pr_err("Still in bist write: 0x%x\n", result);
0284     else if ((result & (1 << 26)) != 0x0)
0285         pr_err("bist write error: 0x%x\n", result);
0286 
0287     return 0;
0288 }
0289 
0290 static int run_bist(adapter_t *adapter, int moduleid)
0291 {
0292     /*run bist*/
0293     (void) bist_wr(adapter,moduleid, 0x00, 0x02);
0294     (void) bist_wr(adapter,moduleid, 0x01, 0x01);
0295 
0296     return 0;
0297 }
0298 
0299 static int check_bist(adapter_t *adapter, int moduleid)
0300 {
0301     int result=0;
0302     int column=0;
0303     /*check bist*/
0304     result = bist_rd(adapter,moduleid, 0x02);
0305     column = ((bist_rd(adapter,moduleid, 0x0e)<<8) +
0306             (bist_rd(adapter,moduleid, 0x0d)));
0307     if ((result & 3) != 0x3)
0308         pr_err("Result: 0x%x  BIST error in ram %d, column: 0x%04x\n",
0309             result, moduleid, column);
0310     return 0;
0311 }
0312 
0313 static int enable_mem(adapter_t *adapter, int moduleid)
0314 {
0315     /*enable mem*/
0316     (void) bist_wr(adapter,moduleid, 0x00, 0x00);
0317     return 0;
0318 }
0319 
0320 static int run_bist_all(adapter_t *adapter)
0321 {
0322     int port = 0;
0323     u32 val = 0;
0324 
0325     vsc_write(adapter, REG_MEM_BIST, 0x5);
0326     vsc_read(adapter, REG_MEM_BIST, &val);
0327 
0328     for (port = 0; port < 12; port++)
0329         vsc_write(adapter, REG_DEV_SETUP(port), 0x0);
0330 
0331     udelay(300);
0332     vsc_write(adapter, REG_SPI4_MISC, 0x00040409);
0333     udelay(300);
0334 
0335     (void) run_bist(adapter,13);
0336     (void) run_bist(adapter,14);
0337     (void) run_bist(adapter,20);
0338     (void) run_bist(adapter,21);
0339     mdelay(200);
0340     (void) check_bist(adapter,13);
0341     (void) check_bist(adapter,14);
0342     (void) check_bist(adapter,20);
0343     (void) check_bist(adapter,21);
0344     udelay(100);
0345     (void) enable_mem(adapter,13);
0346     (void) enable_mem(adapter,14);
0347     (void) enable_mem(adapter,20);
0348     (void) enable_mem(adapter,21);
0349     udelay(300);
0350     vsc_write(adapter, REG_SPI4_MISC, 0x60040400);
0351     udelay(300);
0352     for (port = 0; port < 12; port++)
0353         vsc_write(adapter, REG_DEV_SETUP(port), 0x1);
0354 
0355     udelay(300);
0356     vsc_write(adapter, REG_MEM_BIST, 0x0);
0357     mdelay(10);
0358     return 0;
0359 }
0360 
0361 static int mac_intr_handler(struct cmac *mac)
0362 {
0363     return 0;
0364 }
0365 
0366 static int mac_intr_enable(struct cmac *mac)
0367 {
0368     return 0;
0369 }
0370 
0371 static int mac_intr_disable(struct cmac *mac)
0372 {
0373     return 0;
0374 }
0375 
0376 static int mac_intr_clear(struct cmac *mac)
0377 {
0378     return 0;
0379 }
0380 
0381 /* Expect MAC address to be in network byte order. */
0382 static int mac_set_address(struct cmac* mac, const u8 addr[6])
0383 {
0384     u32 val;
0385     int port = mac->instance->index;
0386 
0387     vsc_write(mac->adapter, REG_MAC_LOW_ADDR(port),
0388           (addr[3] << 16) | (addr[4] << 8) | addr[5]);
0389     vsc_write(mac->adapter, REG_MAC_HIGH_ADDR(port),
0390           (addr[0] << 16) | (addr[1] << 8) | addr[2]);
0391 
0392     vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &val);
0393     val &= ~0xf0000000;
0394     vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, val | (port << 28));
0395 
0396     vsc_write(mac->adapter, REG_ING_FFILT_MASK0,
0397           0xffff0000 | (addr[4] << 8) | addr[5]);
0398     vsc_write(mac->adapter, REG_ING_FFILT_MASK1,
0399           0xffff0000 | (addr[2] << 8) | addr[3]);
0400     vsc_write(mac->adapter, REG_ING_FFILT_MASK2,
0401           0xffff0000 | (addr[0] << 8) | addr[1]);
0402     return 0;
0403 }
0404 
0405 static int mac_get_address(struct cmac *mac, u8 addr[6])
0406 {
0407     u32 addr_lo, addr_hi;
0408     int port = mac->instance->index;
0409 
0410     vsc_read(mac->adapter, REG_MAC_LOW_ADDR(port), &addr_lo);
0411     vsc_read(mac->adapter, REG_MAC_HIGH_ADDR(port), &addr_hi);
0412 
0413     addr[0] = (u8) (addr_hi >> 16);
0414     addr[1] = (u8) (addr_hi >> 8);
0415     addr[2] = (u8) addr_hi;
0416     addr[3] = (u8) (addr_lo >> 16);
0417     addr[4] = (u8) (addr_lo >> 8);
0418     addr[5] = (u8) addr_lo;
0419     return 0;
0420 }
0421 
0422 /* This is intended to reset a port, not the whole MAC */
0423 static int mac_reset(struct cmac *mac)
0424 {
0425     int index = mac->instance->index;
0426 
0427     run_table(mac->adapter, vsc7326_portinit[index],
0428           ARRAY_SIZE(vsc7326_portinit[index]));
0429 
0430     return 0;
0431 }
0432 
0433 static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
0434 {
0435     u32 v;
0436     int port = mac->instance->index;
0437 
0438     vsc_read(mac->adapter, REG_ING_FFILT_UM_EN, &v);
0439     v |= 1 << 12;
0440 
0441     if (t1_rx_mode_promisc(rm))
0442         v &= ~(1 << (port + 16));
0443     else
0444         v |= 1 << (port + 16);
0445 
0446     vsc_write(mac->adapter, REG_ING_FFILT_UM_EN, v);
0447     return 0;
0448 }
0449 
0450 static int mac_set_mtu(struct cmac *mac, int mtu)
0451 {
0452     int port = mac->instance->index;
0453 
0454     /* max_len includes header and FCS */
0455     vsc_write(mac->adapter, REG_MAX_LEN(port), mtu + 14 + 4);
0456     return 0;
0457 }
0458 
0459 static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
0460                    int fc)
0461 {
0462     u32 v;
0463     int enable, port = mac->instance->index;
0464 
0465     if (speed >= 0 && speed != SPEED_10 && speed != SPEED_100 &&
0466         speed != SPEED_1000)
0467         return -1;
0468     if (duplex > 0 && duplex != DUPLEX_FULL)
0469         return -1;
0470 
0471     if (speed >= 0) {
0472         vsc_read(mac->adapter, REG_MODE_CFG(port), &v);
0473         enable = v & 3;             /* save tx/rx enables */
0474         v &= ~0xf;
0475         v |= 4;                     /* full duplex */
0476         if (speed == SPEED_1000)
0477             v |= 8;             /* GigE */
0478         enable |= v;
0479         vsc_write(mac->adapter, REG_MODE_CFG(port), v);
0480 
0481         if (speed == SPEED_1000)
0482             v = 0x82;
0483         else if (speed == SPEED_100)
0484             v = 0x84;
0485         else    /* SPEED_10 */
0486             v = 0x86;
0487         vsc_write(mac->adapter, REG_DEV_SETUP(port), v | 1); /* reset */
0488         vsc_write(mac->adapter, REG_DEV_SETUP(port), v);
0489         vsc_read(mac->adapter, REG_DBG(port), &v);
0490         v &= ~0xff00;
0491         if (speed == SPEED_1000)
0492             v |= 0x400;
0493         else if (speed == SPEED_100)
0494             v |= 0x2000;
0495         else    /* SPEED_10 */
0496             v |= 0xff00;
0497         vsc_write(mac->adapter, REG_DBG(port), v);
0498 
0499         vsc_write(mac->adapter, REG_TX_IFG(port),
0500               speed == SPEED_1000 ? 5 : 0x11);
0501         if (duplex == DUPLEX_HALF)
0502             enable = 0x0;   /* 100 or 10 */
0503         else if (speed == SPEED_1000)
0504             enable = 0xc;
0505         else    /* SPEED_100 or 10 */
0506             enable = 0x4;
0507         enable |= 0x9 << 10;    /* IFG1 */
0508         enable |= 0x6 << 6; /* IFG2 */
0509         enable |= 0x1 << 4; /* VLAN */
0510         enable |= 0x3;      /* RX/TX EN */
0511         vsc_write(mac->adapter, REG_MODE_CFG(port), enable);
0512 
0513     }
0514 
0515     vsc_read(mac->adapter, REG_PAUSE_CFG(port), &v);
0516     v &= 0xfff0ffff;
0517     v |= 0x20000;      /* xon/xoff */
0518     if (fc & PAUSE_RX)
0519         v |= 0x40000;
0520     if (fc & PAUSE_TX)
0521         v |= 0x80000;
0522     if (fc == (PAUSE_RX | PAUSE_TX))
0523         v |= 0x10000;
0524     vsc_write(mac->adapter, REG_PAUSE_CFG(port), v);
0525     return 0;
0526 }
0527 
0528 static int mac_enable(struct cmac *mac, int which)
0529 {
0530     u32 val;
0531     int port = mac->instance->index;
0532 
0533     /* Write the correct WM value when the port is enabled. */
0534     vsc_write(mac->adapter, REG_HIGH_LOW_WM(1,port), WM_ENABLE);
0535 
0536     vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
0537     if (which & MAC_DIRECTION_RX)
0538         val |= 0x2;
0539     if (which & MAC_DIRECTION_TX)
0540         val |= 1;
0541     vsc_write(mac->adapter, REG_MODE_CFG(port), val);
0542     return 0;
0543 }
0544 
0545 static int mac_disable(struct cmac *mac, int which)
0546 {
0547     u32 val;
0548     int i, port = mac->instance->index;
0549 
0550     /* Reset the port, this also writes the correct WM value */
0551     mac_reset(mac);
0552 
0553     vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
0554     if (which & MAC_DIRECTION_RX)
0555         val &= ~0x2;
0556     if (which & MAC_DIRECTION_TX)
0557         val &= ~0x1;
0558     vsc_write(mac->adapter, REG_MODE_CFG(port), val);
0559     vsc_read(mac->adapter, REG_MODE_CFG(port), &val);
0560 
0561     /* Clear stats */
0562     for (i = 0; i <= 0x3a; ++i)
0563         vsc_write(mac->adapter, CRA(4, port, i), 0);
0564 
0565     /* Clear software counters */
0566     memset(&mac->stats, 0, sizeof(struct cmac_statistics));
0567 
0568     return 0;
0569 }
0570 
0571 static void rmon_update(struct cmac *mac, unsigned int addr, u64 *stat)
0572 {
0573     u32 v, lo;
0574 
0575     vsc_read(mac->adapter, addr, &v);
0576     lo = *stat;
0577     *stat = *stat - lo + v;
0578 
0579     if (v == 0)
0580         return;
0581 
0582     if (v < lo)
0583         *stat += (1ULL << 32);
0584 }
0585 
0586 static void port_stats_update(struct cmac *mac)
0587 {
0588     struct {
0589         unsigned int reg;
0590         unsigned int offset;
0591     } hw_stats[] = {
0592 
0593 #define HW_STAT(reg, stat_name) \
0594     { reg, offsetof(struct cmac_statistics, stat_name) / sizeof(u64) }
0595 
0596         /* Rx stats */
0597         HW_STAT(RxUnicast, RxUnicastFramesOK),
0598         HW_STAT(RxMulticast, RxMulticastFramesOK),
0599         HW_STAT(RxBroadcast, RxBroadcastFramesOK),
0600         HW_STAT(Crc, RxFCSErrors),
0601         HW_STAT(RxAlignment, RxAlignErrors),
0602         HW_STAT(RxOversize, RxFrameTooLongErrors),
0603         HW_STAT(RxPause, RxPauseFrames),
0604         HW_STAT(RxJabbers, RxJabberErrors),
0605         HW_STAT(RxFragments, RxRuntErrors),
0606         HW_STAT(RxUndersize, RxRuntErrors),
0607         HW_STAT(RxSymbolCarrier, RxSymbolErrors),
0608         HW_STAT(RxSize1519ToMax, RxJumboFramesOK),
0609 
0610         /* Tx stats (skip collision stats as we are full-duplex only) */
0611         HW_STAT(TxUnicast, TxUnicastFramesOK),
0612         HW_STAT(TxMulticast, TxMulticastFramesOK),
0613         HW_STAT(TxBroadcast, TxBroadcastFramesOK),
0614         HW_STAT(TxPause, TxPauseFrames),
0615         HW_STAT(TxUnderrun, TxUnderrun),
0616         HW_STAT(TxSize1519ToMax, TxJumboFramesOK),
0617     }, *p = hw_stats;
0618     unsigned int port = mac->instance->index;
0619     u64 *stats = (u64 *)&mac->stats;
0620     unsigned int i;
0621 
0622     for (i = 0; i < ARRAY_SIZE(hw_stats); i++)
0623         rmon_update(mac, CRA(0x4, port, p->reg), stats + p->offset);
0624 
0625     rmon_update(mac, REG_TX_OK_BYTES(port), &mac->stats.TxOctetsOK);
0626     rmon_update(mac, REG_RX_OK_BYTES(port), &mac->stats.RxOctetsOK);
0627     rmon_update(mac, REG_RX_BAD_BYTES(port), &mac->stats.RxOctetsBad);
0628 }
0629 
0630 /*
0631  * This function is called periodically to accumulate the current values of the
0632  * RMON counters into the port statistics.  Since the counters are only 32 bits
0633  * some of them can overflow in less than a minute at GigE speeds, so this
0634  * function should be called every 30 seconds or so.
0635  *
0636  * To cut down on reading costs we update only the octet counters at each tick
0637  * and do a full update at major ticks, which can be every 30 minutes or more.
0638  */
0639 static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
0640                                int flag)
0641 {
0642     if (flag == MAC_STATS_UPDATE_FULL ||
0643         mac->instance->ticks >= MAJOR_UPDATE_TICKS) {
0644         port_stats_update(mac);
0645         mac->instance->ticks = 0;
0646     } else {
0647         int port = mac->instance->index;
0648 
0649         rmon_update(mac, REG_RX_OK_BYTES(port),
0650                 &mac->stats.RxOctetsOK);
0651         rmon_update(mac, REG_RX_BAD_BYTES(port),
0652                 &mac->stats.RxOctetsBad);
0653         rmon_update(mac, REG_TX_OK_BYTES(port),
0654                 &mac->stats.TxOctetsOK);
0655         mac->instance->ticks++;
0656     }
0657     return &mac->stats;
0658 }
0659 
0660 static void mac_destroy(struct cmac *mac)
0661 {
0662     kfree(mac);
0663 }
0664 
0665 static const struct cmac_ops vsc7326_ops = {
0666     .destroy                  = mac_destroy,
0667     .reset                    = mac_reset,
0668     .interrupt_handler        = mac_intr_handler,
0669     .interrupt_enable         = mac_intr_enable,
0670     .interrupt_disable        = mac_intr_disable,
0671     .interrupt_clear          = mac_intr_clear,
0672     .enable                   = mac_enable,
0673     .disable                  = mac_disable,
0674     .set_mtu                  = mac_set_mtu,
0675     .set_rx_mode              = mac_set_rx_mode,
0676     .set_speed_duplex_fc      = mac_set_speed_duplex_fc,
0677     .statistics_update        = mac_update_statistics,
0678     .macaddress_get           = mac_get_address,
0679     .macaddress_set           = mac_set_address,
0680 };
0681 
0682 static struct cmac *vsc7326_mac_create(adapter_t *adapter, int index)
0683 {
0684     struct cmac *mac;
0685     u32 val;
0686     int i;
0687 
0688     mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
0689     if (!mac)
0690         return NULL;
0691 
0692     mac->ops = &vsc7326_ops;
0693     mac->instance = (cmac_instance *)(mac + 1);
0694     mac->adapter  = adapter;
0695 
0696     mac->instance->index = index;
0697     mac->instance->ticks = 0;
0698 
0699     i = 0;
0700     do {
0701         u32 vhi, vlo;
0702 
0703         vhi = vlo = 0;
0704         t1_tpi_read(adapter, (REG_LOCAL_STATUS << 2) + 4, &vlo);
0705         udelay(1);
0706         t1_tpi_read(adapter, REG_LOCAL_STATUS << 2, &vhi);
0707         udelay(5);
0708         val = (vhi << 16) | vlo;
0709     } while ((++i < 10000) && (val == 0xffffffff));
0710 
0711     return mac;
0712 }
0713 
0714 static int vsc7326_mac_reset(adapter_t *adapter)
0715 {
0716     vsc7326_full_reset(adapter);
0717     (void) run_bist_all(adapter);
0718     run_table(adapter, vsc7326_reset, ARRAY_SIZE(vsc7326_reset));
0719     return 0;
0720 }
0721 
0722 const struct gmac t1_vsc7326_ops = {
0723     .stats_update_period = STATS_TICK_SECS,
0724     .create              = vsc7326_mac_create,
0725     .reset               = vsc7326_mac_reset,
0726 };