Changeset 26865
- Timestamp:
- 2011-05-09T17:21:58+02:00 (7 years ago)
- Location:
- trunk/target/linux/generic
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/target/linux/generic/files/drivers/net/phy/adm6996.c
r21952 r26865 2 2 * ADM6996 switch driver 3 3 * 4 * swconfig interface based on ar8216.c 5 * 4 6 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org> 7 * VLAN support Copyright (c) 2010, 2011 Peter Lebbing <peter@digitalbrains.com> 5 8 * 6 9 * This program is free software; you can redistribute it and/or modify it … … 8 11 * Free Software Foundation 9 12 */ 13 14 /*#define DEBUG 1*/ 10 15 #include <linux/kernel.h> 11 16 #include <linux/string.h> … … 25 30 #include <linux/ethtool.h> 26 31 #include <linux/phy.h> 32 #include <linux/switch.h> 27 33 28 34 #include <asm/io.h> … … 32 38 33 39 MODULE_DESCRIPTION("Infineon ADM6996 Switch"); 34 MODULE_AUTHOR("Felix Fietkau ");40 MODULE_AUTHOR("Felix Fietkau, Peter Lebbing <peter@digitalbrains.com>"); 35 41 MODULE_LICENSE("GPL"); 36 42 43 enum adm6996_model { 44 ADM6996FC, 45 ADM6996M 46 }; 47 48 static const char * const adm6996_model_name[] = 49 { 50 "ADM6996FC", 51 "ADM6996M" 52 }; 53 37 54 struct adm6996_priv { 55 struct switch_dev dev; 56 struct phy_device *phydev; 57 58 enum adm6996_model model; 59 60 bool enable_vlan; 61 bool vlan_enabled; /* Current hardware state */ 62 63 #ifdef DEBUG 64 u16 addr; /* Debugging: register address to operate on */ 65 #endif 66 67 u16 pvid[ADM_NUM_PORTS]; /* Primary VLAN ID */ 68 69 u16 vlan_id[ADM_NUM_VLANS]; 70 u8 vlan_table[ADM_NUM_VLANS]; /* bitmap, 1 = port is member */ 71 u8 vlan_tagged[ADM_NUM_VLANS]; /* bitmap, 1 = tagged member */ 72 73 struct mutex reg_mutex; 74 38 75 /* use abstraction for regops, we want to add gpio support in the future */ 39 76 u16 (*read)(struct phy_device *phydev, enum admreg reg); … … 41 78 }; 42 79 43 #define to_adm(_ phy) ((struct adm6996_priv *) (_phy)->priv)44 80 #define to_adm(_dev) container_of(_dev, struct adm6996_priv, dev) 81 #define phy_to_adm(_phy) ((struct adm6996_priv *) (_phy)->priv) 45 82 46 83 static inline u16 47 84 r16(struct phy_device *pdev, enum admreg reg) 48 85 { 49 return to_adm(pdev)->read(pdev, reg);86 return phy_to_adm(pdev)->read(pdev, reg); 50 87 } 51 88 … … 53 90 w16(struct phy_device *pdev, enum admreg reg, u16 val) 54 91 { 55 to_adm(pdev)->write(pdev, reg, val);92 phy_to_adm(pdev)->write(pdev, reg, val); 56 93 } 57 94 … … 69 106 } 70 107 108 static int 109 adm6996_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, 110 struct switch_val *val) 111 { 112 struct adm6996_priv *priv = to_adm(dev); 113 114 if (val->value.i > 1) 115 return -EINVAL; 116 117 priv->enable_vlan = val->value.i; 118 119 return 0; 120 }; 121 122 static int 123 adm6996_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, 124 struct switch_val *val) 125 { 126 struct adm6996_priv *priv = to_adm(dev); 127 128 val->value.i = priv->enable_vlan; 129 130 return 0; 131 }; 132 133 #ifdef DEBUG 134 135 static int 136 adm6996_set_addr(struct switch_dev *dev, const struct switch_attr *attr, 137 struct switch_val *val) 138 { 139 struct adm6996_priv *priv = to_adm(dev); 140 141 if (val->value.i > 1023) 142 return -EINVAL; 143 144 priv->addr = val->value.i; 145 146 return 0; 147 }; 148 149 static int 150 adm6996_get_addr(struct switch_dev *dev, const struct switch_attr *attr, 151 struct switch_val *val) 152 { 153 struct adm6996_priv *priv = to_adm(dev); 154 155 val->value.i = priv->addr; 156 157 return 0; 158 }; 159 160 static int 161 adm6996_set_data(struct switch_dev *dev, const struct switch_attr *attr, 162 struct switch_val *val) 163 { 164 struct adm6996_priv *priv = to_adm(dev); 165 166 if (val->value.i > 65535) 167 return -EINVAL; 168 169 w16(priv->phydev, priv->addr, val->value.i); 170 171 return 0; 172 }; 173 174 static int 175 adm6996_get_data(struct switch_dev *dev, const struct switch_attr *attr, 176 struct switch_val *val) 177 { 178 struct adm6996_priv *priv = to_adm(dev); 179 180 val->value.i = r16(priv->phydev, priv->addr); 181 182 return 0; 183 }; 184 185 #endif /* def DEBUG */ 186 187 static int 188 adm6996_set_pvid(struct switch_dev *dev, int port, int vlan) 189 { 190 struct adm6996_priv *priv = to_adm(dev); 191 192 dev_dbg (&priv->phydev->dev, "set_pvid port %d vlan %d\n", port 193 , vlan); 194 195 if (vlan > ADM_VLAN_MAX_ID) 196 return -EINVAL; 197 198 priv->pvid[port] = vlan; 199 200 return 0; 201 } 202 203 static int 204 adm6996_get_pvid(struct switch_dev *dev, int port, int *vlan) 205 { 206 struct adm6996_priv *priv = to_adm(dev); 207 208 dev_dbg (&priv->phydev->dev, "get_pvid port %d\n", port); 209 *vlan = priv->pvid[port]; 210 211 return 0; 212 } 213 214 static int 215 adm6996_set_vid(struct switch_dev *dev, const struct switch_attr *attr, 216 struct switch_val *val) 217 { 218 struct adm6996_priv *priv = to_adm(dev); 219 220 dev_dbg (&priv->phydev->dev, "set_vid port %d vid %d\n", val->port_vlan, 221 val->value.i); 222 223 if (val->value.i > ADM_VLAN_MAX_ID) 224 return -EINVAL; 225 226 priv->vlan_id[val->port_vlan] = val->value.i; 227 228 return 0; 229 }; 230 231 static int 232 adm6996_get_vid(struct switch_dev *dev, const struct switch_attr *attr, 233 struct switch_val *val) 234 { 235 struct adm6996_priv *priv = to_adm(dev); 236 237 dev_dbg (&priv->phydev->dev, "get_vid port %d\n", val->port_vlan); 238 239 val->value.i = priv->vlan_id[val->port_vlan]; 240 241 return 0; 242 }; 243 244 static int 245 adm6996_get_ports(struct switch_dev *dev, struct switch_val *val) 246 { 247 struct adm6996_priv *priv = to_adm(dev); 248 u8 ports = priv->vlan_table[val->port_vlan]; 249 u8 tagged = priv->vlan_tagged[val->port_vlan]; 250 int i; 251 252 dev_dbg (&priv->phydev->dev, "get_ports port_vlan %d\n", 253 val->port_vlan); 254 255 val->len = 0; 256 257 for (i = 0; i < ADM_NUM_PORTS; i++) { 258 struct switch_port *p; 259 260 if (!(ports & (1 << i))) 261 continue; 262 263 p = &val->value.ports[val->len++]; 264 p->id = i; 265 if (tagged & (1 << i)) 266 p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); 267 else 268 p->flags = 0; 269 } 270 271 return 0; 272 }; 273 274 static int 275 adm6996_set_ports(struct switch_dev *dev, struct switch_val *val) 276 { 277 struct adm6996_priv *priv = to_adm(dev); 278 u8 *ports = &priv->vlan_table[val->port_vlan]; 279 u8 *tagged = &priv->vlan_tagged[val->port_vlan]; 280 int i; 281 282 dev_dbg (&priv->phydev->dev, "set_ports port_vlan %d ports", 283 val->port_vlan); 284 285 *ports = 0; 286 *tagged = 0; 287 288 for (i = 0; i < val->len; i++) { 289 struct switch_port *p = &val->value.ports[i]; 290 291 #ifdef DEBUG 292 pr_cont(" %d%s", p->id, 293 ((p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ? "T" : 294 "")); 295 #endif 296 297 if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) 298 *tagged |= (1 << p->id); 299 300 *ports |= (1 << p->id); 301 } 302 303 #ifdef DEBUG 304 pr_cont("\n"); 305 #endif 306 307 return 0; 308 }; 309 310 /* 311 * Precondition: reg_mutex must be held 312 */ 313 static void 314 adm6996_enable_vlan(struct adm6996_priv *priv) 315 { 316 u16 reg; 317 318 reg = r16(priv->phydev, ADM_OTBE_P2_PVID); 319 reg &= ~(ADM_OTBE_MASK); 320 w16(priv->phydev, ADM_OTBE_P2_PVID, reg); 321 reg = r16(priv->phydev, ADM_IFNTE); 322 reg &= ~(ADM_IFNTE_MASK); 323 w16(priv->phydev, ADM_IFNTE, reg); 324 reg = r16(priv->phydev, ADM_VID_CHECK); 325 reg |= ADM_VID_CHECK_MASK; 326 w16(priv->phydev, ADM_VID_CHECK, reg); 327 reg = r16(priv->phydev, ADM_SYSC0); 328 reg |= ADM_NTTE; 329 reg &= ~(ADM_RVID1); 330 w16(priv->phydev, ADM_SYSC0, reg); 331 reg = r16(priv->phydev, ADM_SYSC3); 332 reg |= ADM_TBV; 333 w16(priv->phydev, ADM_SYSC3, reg); 334 335 }; 336 337 /* 338 * Disable VLANs 339 * 340 * Sets VLAN mapping for port-based VLAN with all ports connected to 341 * eachother (this is also the power-on default). 342 * 343 * Precondition: reg_mutex must be held 344 */ 345 static void 346 adm6996_disable_vlan(struct adm6996_priv *priv) 347 { 348 u16 reg; 349 int i; 350 351 for (i = 0; i < ADM_NUM_PORTS; i++) { 352 reg = ADM_VLAN_FILT_MEMBER_MASK; 353 w16(priv->phydev, ADM_VLAN_FILT_L(i), reg); 354 reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(1); 355 w16(priv->phydev, ADM_VLAN_FILT_H(i), reg); 356 } 357 358 reg = r16(priv->phydev, ADM_OTBE_P2_PVID); 359 reg |= ADM_OTBE_MASK; 360 w16(priv->phydev, ADM_OTBE_P2_PVID, reg); 361 reg = r16(priv->phydev, ADM_IFNTE); 362 reg |= ADM_IFNTE_MASK; 363 w16(priv->phydev, ADM_IFNTE, reg); 364 reg = r16(priv->phydev, ADM_VID_CHECK); 365 reg &= ~(ADM_VID_CHECK_MASK); 366 w16(priv->phydev, ADM_VID_CHECK, reg); 367 reg = r16(priv->phydev, ADM_SYSC0); 368 reg &= ~(ADM_NTTE); 369 reg |= ADM_RVID1; 370 w16(priv->phydev, ADM_SYSC0, reg); 371 reg = r16(priv->phydev, ADM_SYSC3); 372 reg &= ~(ADM_TBV); 373 w16(priv->phydev, ADM_SYSC3, reg); 374 } 375 376 /* 377 * Precondition: reg_mutex must be held 378 */ 379 static void 380 adm6996_apply_port_pvids(struct adm6996_priv *priv) 381 { 382 u16 reg; 383 int i; 384 385 for (i = 0; i < ADM_NUM_PORTS; i++) { 386 reg = r16(priv->phydev, adm_portcfg[i]); 387 reg &= ~(ADM_PORTCFG_PVID_MASK); 388 reg |= ADM_PORTCFG_PVID(priv->pvid[i]); 389 w16(priv->phydev, adm_portcfg[i], reg); 390 } 391 392 w16(priv->phydev, ADM_P0_PVID, ADM_P0_PVID_VAL(priv->pvid[0])); 393 w16(priv->phydev, ADM_P1_PVID, ADM_P1_PVID_VAL(priv->pvid[1])); 394 reg = r16(priv->phydev, ADM_OTBE_P2_PVID); 395 reg &= ~(ADM_P2_PVID_MASK); 396 reg |= ADM_P2_PVID_VAL(priv->pvid[2]); 397 w16(priv->phydev, ADM_OTBE_P2_PVID, reg); 398 reg = ADM_P3_PVID_VAL(priv->pvid[3]); 399 reg |= ADM_P4_PVID_VAL(priv->pvid[4]); 400 w16(priv->phydev, ADM_P3_P4_PVID, reg); 401 w16(priv->phydev, ADM_P5_PVID, ADM_P5_PVID_VAL(priv->pvid[5])); 402 } 403 404 /* 405 * Precondition: reg_mutex must be held 406 */ 407 static void 408 adm6996_apply_vlan_filters(struct adm6996_priv *priv) 409 { 410 u8 ports, tagged; 411 u16 vid, reg; 412 int i; 413 414 for (i = 0; i < ADM_NUM_VLANS; i++) { 415 vid = priv->vlan_id[i]; 416 ports = priv->vlan_table[i]; 417 tagged = priv->vlan_tagged[i]; 418 419 if (ports == 0) { 420 /* Disable VLAN entry */ 421 w16(priv->phydev, ADM_VLAN_FILT_H(i), 0); 422 w16(priv->phydev, ADM_VLAN_FILT_L(i), 0); 423 continue; 424 } 425 426 reg = ADM_VLAN_FILT_MEMBER(ports); 427 reg |= ADM_VLAN_FILT_TAGGED(tagged); 428 w16(priv->phydev, ADM_VLAN_FILT_L(i), reg); 429 reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(vid); 430 w16(priv->phydev, ADM_VLAN_FILT_H(i), reg); 431 } 432 } 433 434 static int 435 adm6996_hw_apply(struct switch_dev *dev) 436 { 437 struct adm6996_priv *priv = to_adm(dev); 438 439 dev_dbg(&priv->phydev->dev, "hw_apply\n"); 440 441 mutex_lock(&priv->reg_mutex); 442 443 if (!priv->enable_vlan) { 444 if (priv->vlan_enabled) { 445 adm6996_disable_vlan(priv); 446 priv->vlan_enabled = 0; 447 } 448 goto out; 449 } 450 451 if (!priv->vlan_enabled) { 452 adm6996_enable_vlan(priv); 453 priv->vlan_enabled = 1; 454 } 455 456 adm6996_apply_port_pvids(priv); 457 adm6996_apply_vlan_filters(priv); 458 459 out: 460 mutex_unlock(&priv->reg_mutex); 461 462 return 0; 463 } 464 465 /* 466 * Reset the switch 467 * 468 * The ADM6996 can't do a software-initiated reset, so we just initialise the 469 * registers we support in this driver. 470 * 471 * Precondition: reg_mutex must be held 472 */ 473 static void 474 adm6996_perform_reset (struct adm6996_priv *priv) 475 { 476 int i; 477 478 /* initialize port and vlan settings */ 479 for (i = 0; i < ADM_NUM_PORTS - 1; i++) { 480 w16(priv->phydev, adm_portcfg[i], ADM_PORTCFG_INIT | 481 ADM_PORTCFG_PVID(0)); 482 } 483 w16(priv->phydev, adm_portcfg[5], ADM_PORTCFG_CPU); 484 485 /* reset all PHY ports */ 486 for (i = 0; i < ADM_PHY_PORTS; i++) { 487 w16(priv->phydev, ADM_PHY_PORT(i), ADM_PHYCFG_INIT); 488 } 489 490 priv->enable_vlan = 0; 491 priv->vlan_enabled = 0; 492 493 for (i = 0; i < ADM_NUM_PORTS; i++) { 494 priv->pvid[i] = 0; 495 } 496 497 for (i = 0; i < ADM_NUM_VLANS; i++) { 498 priv->vlan_id[i] = i; 499 priv->vlan_table[i] = 0; 500 priv->vlan_tagged[i] = 0; 501 } 502 503 if (priv->model == ADM6996M) { 504 /* Clear VLAN priority map so prio's are unused */ 505 w16 (priv->phydev, ADM_VLAN_PRIOMAP, 0); 506 507 adm6996_disable_vlan(priv); 508 adm6996_apply_port_pvids(priv); 509 } 510 } 511 512 static int 513 adm6996_reset_switch(struct switch_dev *dev) 514 { 515 struct adm6996_priv *priv = to_adm(dev); 516 517 dev_dbg (&priv->phydev->dev, "reset\n"); 518 mutex_lock(&priv->reg_mutex); 519 adm6996_perform_reset (priv); 520 mutex_unlock(&priv->reg_mutex); 521 return 0; 522 } 523 524 static struct switch_attr adm6996_globals[] = { 525 { 526 .type = SWITCH_TYPE_INT, 527 .name = "enable_vlan", 528 .description = "Enable VLANs", 529 .set = adm6996_set_enable_vlan, 530 .get = adm6996_get_enable_vlan, 531 }, 532 #ifdef DEBUG 533 { 534 .type = SWITCH_TYPE_INT, 535 .name = "addr", 536 .description = 537 "Direct register access: set register address (0 - 1023)", 538 .set = adm6996_set_addr, 539 .get = adm6996_get_addr, 540 }, 541 { 542 .type = SWITCH_TYPE_INT, 543 .name = "data", 544 .description = 545 "Direct register access: read/write to register (0 - 65535)", 546 .set = adm6996_set_data, 547 .get = adm6996_get_data, 548 }, 549 #endif /* def DEBUG */ 550 }; 551 552 static struct switch_attr adm6996_port[] = { 553 }; 554 555 static struct switch_attr adm6996_vlan[] = { 556 { 557 .type = SWITCH_TYPE_INT, 558 .name = "vid", 559 .description = "VLAN ID", 560 .set = adm6996_set_vid, 561 .get = adm6996_get_vid, 562 }, 563 }; 564 565 static const struct switch_dev_ops adm6996_ops = { 566 .attr_global = { 567 .attr = adm6996_globals, 568 .n_attr = ARRAY_SIZE(adm6996_globals), 569 }, 570 .attr_port = { 571 .attr = adm6996_port, 572 .n_attr = ARRAY_SIZE(adm6996_port), 573 }, 574 .attr_vlan = { 575 .attr = adm6996_vlan, 576 .n_attr = ARRAY_SIZE(adm6996_vlan), 577 }, 578 .get_port_pvid = adm6996_get_pvid, 579 .set_port_pvid = adm6996_set_pvid, 580 .get_vlan_ports = adm6996_get_ports, 581 .set_vlan_ports = adm6996_set_ports, 582 .apply_config = adm6996_hw_apply, 583 .reset_switch = adm6996_reset_switch, 584 }; 71 585 72 586 static int adm6996_config_init(struct phy_device *pdev) 73 587 { 74 int i; 75 76 printk("%s: ADM6996 PHY driver attached.\n", pdev->attached_dev->name); 588 struct adm6996_priv *priv; 589 struct switch_dev *swdev; 590 591 int ret; 592 u16 test, old; 593 77 594 pdev->supported = ADVERTISED_100baseT_Full; 78 595 pdev->advertising = ADVERTISED_100baseT_Full; 79 596 80 /* initialize port and vlan settings */ 81 for (i = 0; i < ADM_PHY_PORTS; i++) { 82 w16(pdev, adm_portcfg[i], ADM_PORTCFG_INIT | 83 ADM_PORTCFG_PVID((i == ADM_WAN_PORT) ? 1 : 0)); 84 } 85 w16(pdev, adm_portcfg[5], ADM_PORTCFG_CPU); 86 87 /* reset all ports */ 88 for (i = 0; i < ADM_PHY_PORTS; i++) { 89 w16(pdev, ADM_PHY_PORT(i), ADM_PHYCFG_INIT); 90 } 91 92 return 0; 93 } 94 597 if (pdev->addr != 0) { 598 pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n" 599 , pdev->attached_dev->name, pdev->addr); 600 return 0; 601 } 602 603 priv = kzalloc(sizeof(struct adm6996_priv), GFP_KERNEL); 604 if (priv == NULL) 605 return -ENOMEM; 606 607 mutex_init(&priv->reg_mutex); 608 priv->phydev = pdev; 609 priv->read = adm6996_read_mii_reg; 610 priv->write = adm6996_write_mii_reg; 611 pdev->priv = priv; 612 613 /* Detect type of chip */ 614 old = r16(pdev, ADM_VID_CHECK); 615 test = old ^ (1 << 12); 616 w16(pdev, ADM_VID_CHECK, test); 617 test ^= r16(pdev, ADM_VID_CHECK); 618 if (test & (1 << 12)) { 619 /* 620 * Bit 12 of this register is read-only. 621 * This is the FC model. 622 */ 623 priv->model = ADM6996FC; 624 } else { 625 /* Bit 12 is read-write. This is the M model. */ 626 priv->model = ADM6996M; 627 w16(pdev, ADM_VID_CHECK, old); 628 } 629 630 swdev = &priv->dev; 631 swdev->name = (adm6996_model_name[priv->model]); 632 swdev->cpu_port = ADM_CPU_PORT; 633 swdev->ports = ADM_NUM_PORTS; 634 swdev->vlans = ADM_NUM_VLANS; 635 swdev->ops = &adm6996_ops; 636 637 pr_info ("%s: %s model PHY found.\n", pdev->attached_dev->name, 638 swdev->name); 639 640 mutex_lock(&priv->reg_mutex); 641 adm6996_perform_reset (priv); 642 mutex_unlock(&priv->reg_mutex); 643 644 if (priv->model == ADM6996M) { 645 if ((ret = register_switch(swdev, pdev->attached_dev)) < 0) { 646 kfree(priv); 647 return ret; 648 } 649 } 650 651 return 0; 652 } 653 654 /* 655 * Warning: phydev->priv is NULL if phydev->addr != 0 656 */ 95 657 static int adm6996_read_status(struct phy_device *phydev) 96 658 { … … 101 663 } 102 664 665 /* 666 * Warning: phydev->priv is NULL if phydev->addr != 0 667 */ 103 668 static int adm6996_config_aneg(struct phy_device *phydev) 104 669 { … … 110 675 struct mii_bus *bus = dev->bus; 111 676 u16 reg; 677 678 /* Our custom registers are at PHY addresses 0-10. Claim those. */ 679 if (dev->addr > 10) 680 return 0; 112 681 113 682 /* look for the switch on the bus */ … … 121 690 122 691 dev->phy_id = (ADM_SIG0_VAL << 16) | ADM_SIG1_VAL; 692 123 693 return 0; 124 694 } … … 126 696 static int adm6996_probe(struct phy_device *pdev) 127 697 { 128 struct adm6996_priv *priv;129 130 priv = kzalloc(sizeof(struct adm6996_priv), GFP_KERNEL);131 if (priv == NULL)132 return -ENOMEM;133 134 priv->read = adm6996_read_mii_reg;135 priv->write = adm6996_write_mii_reg;136 pdev->priv = priv;137 698 return 0; 138 699 } … … 140 701 static void adm6996_remove(struct phy_device *pdev) 141 702 { 142 kfree(pdev->priv); 703 struct adm6996_priv *priv = phy_to_adm(pdev); 704 705 if (priv != NULL && priv->model == ADM6996M) 706 unregister_switch(&priv->dev); 707 708 kfree(priv); 143 709 } 144 710 -
trunk/target/linux/generic/files/drivers/net/phy/adm6996.h
r21952 r26865 3 3 * 4 4 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org> 5 * Copyright (c) 2010,2011 Peter Lebbing <peter@digitalbrains.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify it … … 11 12 #define __ADM6996_H 12 13 13 #define ADM_PHY_PORTS 5 14 /* 15 * ADM_PHY_PORTS: Number of ports with a PHY. 16 * We only control ports 0 to 3, because if 4 is connected, it is most likely 17 * not connected to the switch but to a separate MII and MAC for the WAN port. 18 */ 19 #define ADM_PHY_PORTS 4 20 #define ADM_NUM_PORTS 6 14 21 #define ADM_CPU_PORT 5 15 #define ADM_WAN_PORT 0 /* FIXME: dynamic ? */ 22 23 #define ADM_NUM_VLANS 16 24 #define ADM_VLAN_MAX_ID 4094 16 25 17 26 enum admreg { … … 23 32 ADM_P4_CFG = ADM_EEPROM_BASE + 8, 24 33 ADM_P5_CFG = ADM_EEPROM_BASE + 9, 34 ADM_SYSC0 = ADM_EEPROM_BASE + 0xa, 35 ADM_VLAN_PRIOMAP = ADM_EEPROM_BASE + 0xe, 36 ADM_SYSC3 = ADM_EEPROM_BASE + 0x11, 37 /* Input Force No Tag Enable */ 38 ADM_IFNTE = ADM_EEPROM_BASE + 0x20, 39 ADM_VID_CHECK = ADM_EEPROM_BASE + 0x26, 40 ADM_P0_PVID = ADM_EEPROM_BASE + 0x28, 41 ADM_P1_PVID = ADM_EEPROM_BASE + 0x29, 42 /* Output Tag Bypass Enable and P2 PVID */ 43 ADM_OTBE_P2_PVID = ADM_EEPROM_BASE + 0x2a, 44 ADM_P3_P4_PVID = ADM_EEPROM_BASE + 0x2b, 45 ADM_P5_PVID = ADM_EEPROM_BASE + 0x2c, 25 46 ADM_EEPROM_EXT_BASE = 0x40, 47 #define ADM_VLAN_FILT_L(n) (ADM_EEPROM_EXT_BASE + 2 * (n)) 48 #define ADM_VLAN_FILT_H(n) (ADM_EEPROM_EXT_BASE + 1 + 2 * (n)) 26 49 ADM_COUNTER_BASE = 0xa0, 27 50 ADM_SIG0 = ADM_COUNTER_BASE + 0, … … 32 55 33 56 /* Chip identification patterns */ 34 #define ADM_SIG0_MASK 0xfff 035 #define ADM_SIG0_VAL 0x102 057 #define ADM_SIG0_MASK 0xffff 58 #define ADM_SIG0_VAL 0x1023 36 59 #define ADM_SIG1_MASK 0xffff 37 60 #define ADM_SIG1_VAL 0x0007 … … 85 108 }; 86 109 87 #define ADM_PORTCFG_PPID( N) ((n & 0x3) << 8)110 #define ADM_PORTCFG_PPID(n) ((n & 0x3) << 8) 88 111 #define ADM_PORTCFG_PVID(n) ((n & 0xf) << 10) 112 #define ADM_PORTCFG_PVID_MASK (0xf << 10) 113 114 #define ADM_IFNTE_MASK (0x3f << 9) 115 #define ADM_VID_CHECK_MASK (0x3f << 6) 116 117 #define ADM_P0_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) 118 #define ADM_P1_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) 119 #define ADM_P2_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) 120 #define ADM_P3_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) 121 #define ADM_P4_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 8) 122 #define ADM_P5_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) 123 #define ADM_P2_PVID_MASK 0xff 124 125 #define ADM_OTBE(n) (((n) & 0x3f) << 8) 126 #define ADM_OTBE_MASK (0x3f << 8) 127 128 /* ADM_SYSC0 */ 129 enum { 130 ADM_NTTE = (1 << 2), /* New Tag Transmit Enable */ 131 ADM_RVID1 = (1 << 8) /* Replace VLAN ID 1 */ 132 }; 133 134 /* Tag Based VLAN in ADM_SYSC3 */ 135 #define ADM_TBV (1 << 5) 89 136 90 137 static const u8 adm_portcfg[] = { … … 97 144 }; 98 145 146 /* Fields in ADM_VLAN_FILT_L(x) */ 147 #define ADM_VLAN_FILT_FID(n) (((n) & 0xf) << 12) 148 #define ADM_VLAN_FILT_TAGGED(n) (((n) & 0x3f) << 6) 149 #define ADM_VLAN_FILT_MEMBER(n) (((n) & 0x3f) << 0) 150 #define ADM_VLAN_FILT_MEMBER_MASK 0x3f 151 /* Fields in ADM_VLAN_FILT_H(x) */ 152 #define ADM_VLAN_FILT_VALID (1 << 15) 153 #define ADM_VLAN_FILT_VID(n) (((n) & 0xfff) << 0) 154 155 99 156 /* 100 157 * Split the register address in phy id and register -
trunk/target/linux/generic/patches-2.6.30/620-phy_adm6996.patch
r21952 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -82,6 +82,1 1@@ config LSI_ET1011C_PHY3 @@ -82,6 +82,13 @@ config LSI_ET1011C_PHY 4 4 ---help--- 5 5 Supports the LSI ET1011C PHY. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.31/620-phy_adm6996.patch
r21952 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -82,6 +82,1 1@@ config LSI_ET1011C_PHY3 @@ -82,6 +82,13 @@ config LSI_ET1011C_PHY 4 4 ---help--- 5 5 Supports the LSI ET1011C PHY. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.32/620-phy_adm6996.patch
r21952 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -88,6 +88,1 1@@ config LSI_ET1011C_PHY3 @@ -88,6 +88,13 @@ config LSI_ET1011C_PHY 4 4 ---help--- 5 5 Supports the LSI ET1011C PHY. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.36/620-phy_adm6996.patch
r21952 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -93,6 +93,1 1@@ config MICREL_PHY3 @@ -93,6 +93,13 @@ config MICREL_PHY 4 4 ---help--- 5 5 Supports the KSZ9021, VSC8201, KS8001 PHYs. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.37/720-phy_adm6996.patch
r26692 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -98,6 +98,1 1@@ config MICREL_PHY3 @@ -98,6 +98,13 @@ config MICREL_PHY 4 4 ---help--- 5 5 Supports the KSZ9021, VSC8201, KS8001 PHYs. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.38/720-phy_adm6996.patch
r26690 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -98,6 +98,1 1@@ config MICREL_PHY3 @@ -98,6 +98,13 @@ config MICREL_PHY 4 4 ---help--- 5 5 Supports the KSZ9021, VSC8201, KS8001 PHYs. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY -
trunk/target/linux/generic/patches-2.6.39/720-phy_adm6996.patch
r26691 r26865 1 1 --- a/drivers/net/phy/Kconfig 2 2 +++ b/drivers/net/phy/Kconfig 3 @@ -97,6 +97,1 1@@ config MICREL_PHY3 @@ -97,6 +97,13 @@ config MICREL_PHY 4 4 ---help--- 5 5 Supports the KSZ9021, VSC8201, KS8001 PHYs. … … 7 7 +config ADM6996_PHY 8 8 + tristate "Driver for ADM6996 switches" 9 + select SWCONFIG 9 10 + ---help--- 10 + Currently supports the ADM6996F switch 11 + Currently supports the ADM6996FC and ADM6996M switches. 12 + Support for FC is very limited. 11 13 + 12 14 config FIXED_PHY
Note: See TracChangeset
for help on using the changeset viewer.