aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMugunthan V N <mugunthanvnm@ti.com>2013-02-11 04:52:20 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-12 16:15:10 -0500
commitd9ba8f9e6298af71ec1c1fd3d88c3ef68abd0ec3 (patch)
tree933b4cdcb097e37e8eaea6970f791e862040bd0b
parent9232b16df2167c8afcb89de39ee85f5091ebacff (diff)
driver: net: ethernet: cpsw: dual emac interface implementation
The CPSW switch can act as Dual EMAC by segregating the switch ports using VLAN and port VLAN as per the TRM description in 14.3.2.10.2 Dual Mac Mode Following CPSW components will be common for both the interfaces. * Interrupt source is common for both eth interfaces * Interrupt pacing is common for both interfaces * Hardware statistics is common for all the ports * CPDMA is common for both eth interface * CPTS is common for both the interface and it should not be enabled on both the interface as timestamping information doesn't contain port information. Constrains * Reserved VID of One port should not be used in other interface which will enable switching functionality * Same VID must not be used in both the interface which will enable switching functionality Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/cpsw.txt2
-rw-r--r--drivers/net/ethernet/ti/cpsw.c335
-rw-r--r--include/linux/platform_data/cpsw.h3
3 files changed, 288 insertions, 52 deletions
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index 6ddd0286a9b7..ecfdf756d10f 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -24,6 +24,8 @@ Required properties:
24Optional properties: 24Optional properties:
25- ti,hwmods : Must be "cpgmac0" 25- ti,hwmods : Must be "cpgmac0"
26- no_bd_ram : Must be 0 or 1 26- no_bd_ram : Must be 0 or 1
27- dual_emac : Specifies Switch to act as Dual EMAC
28- dual_emac_res_vlan : Specifies VID to be used to segregate the ports
27 29
28Note: "ti,hwmods" field is used to fetch the base address and irq 30Note: "ti,hwmods" field is used to fetch the base address and irq
29resources from TI, omap hwmod data base during device registration. 31resources from TI, omap hwmod data base during device registration.
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 4b964bb02d4c..4ceed6e0f1be 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -122,6 +122,10 @@ do { \
122#define CPSW_VLAN_AWARE BIT(1) 122#define CPSW_VLAN_AWARE BIT(1)
123#define CPSW_ALE_VLAN_AWARE 1 123#define CPSW_ALE_VLAN_AWARE 1
124 124
125#define CPSW_FIFO_NORMAL_MODE (0 << 15)
126#define CPSW_FIFO_DUAL_MAC_MODE (1 << 15)
127#define CPSW_FIFO_RATE_LIMIT_MODE (2 << 15)
128
125#define cpsw_enable_irq(priv) \ 129#define cpsw_enable_irq(priv) \
126 do { \ 130 do { \
127 u32 i; \ 131 u32 i; \
@@ -254,7 +258,7 @@ struct cpsw_ss_regs {
254struct cpsw_host_regs { 258struct cpsw_host_regs {
255 u32 max_blks; 259 u32 max_blks;
256 u32 blk_cnt; 260 u32 blk_cnt;
257 u32 flow_thresh; 261 u32 tx_in_ctl;
258 u32 port_vlan; 262 u32 port_vlan;
259 u32 tx_pri_map; 263 u32 tx_pri_map;
260 u32 cpdma_tx_pri_map; 264 u32 cpdma_tx_pri_map;
@@ -281,6 +285,9 @@ struct cpsw_slave {
281 u32 mac_control; 285 u32 mac_control;
282 struct cpsw_slave_data *data; 286 struct cpsw_slave_data *data;
283 struct phy_device *phy; 287 struct phy_device *phy;
288 struct net_device *ndev;
289 u32 port_vlan;
290 u32 open_stat;
284}; 291};
285 292
286static inline u32 slave_read(struct cpsw_slave *slave, u32 offset) 293static inline u32 slave_read(struct cpsw_slave *slave, u32 offset)
@@ -320,15 +327,63 @@ struct cpsw_priv {
320 u32 irqs_table[4]; 327 u32 irqs_table[4];
321 u32 num_irqs; 328 u32 num_irqs;
322 struct cpts *cpts; 329 struct cpts *cpts;
330 u32 emac_port;
323}; 331};
324 332
325#define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi) 333#define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi)
326#define for_each_slave(priv, func, arg...) \ 334#define for_each_slave(priv, func, arg...) \
327 do { \ 335 do { \
328 int idx; \ 336 int idx; \
329 for (idx = 0; idx < (priv)->data.slaves; idx++) \ 337 if (priv->data.dual_emac) \
330 (func)((priv)->slaves + idx, ##arg); \ 338 (func)((priv)->slaves + priv->emac_port, ##arg);\
339 else \
340 for (idx = 0; idx < (priv)->data.slaves; idx++) \
341 (func)((priv)->slaves + idx, ##arg); \
342 } while (0)
343#define cpsw_get_slave_ndev(priv, __slave_no__) \
344 (priv->slaves[__slave_no__].ndev)
345#define cpsw_get_slave_priv(priv, __slave_no__) \
346 ((priv->slaves[__slave_no__].ndev) ? \
347 netdev_priv(priv->slaves[__slave_no__].ndev) : NULL) \
348
349#define cpsw_dual_emac_src_port_detect(status, priv, ndev, skb) \
350 do { \
351 if (!priv->data.dual_emac) \
352 break; \
353 if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
354 ndev = cpsw_get_slave_ndev(priv, 0); \
355 priv = netdev_priv(ndev); \
356 skb->dev = ndev; \
357 } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
358 ndev = cpsw_get_slave_ndev(priv, 1); \
359 priv = netdev_priv(ndev); \
360 skb->dev = ndev; \
361 } \
331 } while (0) 362 } while (0)
363#define cpsw_add_mcast(priv, addr) \
364 do { \
365 if (priv->data.dual_emac) { \
366 struct cpsw_slave *slave = priv->slaves + \
367 priv->emac_port; \
368 int slave_port = cpsw_get_slave_port(priv, \
369 slave->slave_num); \
370 cpsw_ale_add_mcast(priv->ale, addr, \
371 1 << slave_port | 1 << priv->host_port, \
372 ALE_VLAN, slave->port_vlan, 0); \
373 } else { \
374 cpsw_ale_add_mcast(priv->ale, addr, \
375 ALE_ALL_PORTS << priv->host_port, \
376 0, 0, 0); \
377 } \
378 } while (0)
379
380static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
381{
382 if (priv->host_port == 0)
383 return slave_num + 1;
384 else
385 return slave_num;
386}
332 387
333static void cpsw_ndo_set_rx_mode(struct net_device *ndev) 388static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
334{ 389{
@@ -348,8 +403,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
348 403
349 /* program multicast address list into ALE register */ 404 /* program multicast address list into ALE register */
350 netdev_for_each_mc_addr(ha, ndev) { 405 netdev_for_each_mc_addr(ha, ndev) {
351 cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr, 406 cpsw_add_mcast(priv, (u8 *)ha->addr);
352 ALE_ALL_PORTS << priv->host_port, 0, 0, 0);
353 } 407 }
354 } 408 }
355} 409}
@@ -396,6 +450,8 @@ void cpsw_rx_handler(void *token, int len, int status)
396 struct cpsw_priv *priv = netdev_priv(ndev); 450 struct cpsw_priv *priv = netdev_priv(ndev);
397 int ret = 0; 451 int ret = 0;
398 452
453 cpsw_dual_emac_src_port_detect(status, priv, ndev, skb);
454
399 /* free and bail if we are shutting down */ 455 /* free and bail if we are shutting down */
400 if (unlikely(!netif_running(ndev)) || 456 if (unlikely(!netif_running(ndev)) ||
401 unlikely(!netif_carrier_ok(ndev))) { 457 unlikely(!netif_carrier_ok(ndev))) {
@@ -437,18 +493,17 @@ static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
437 cpsw_intr_disable(priv); 493 cpsw_intr_disable(priv);
438 cpsw_disable_irq(priv); 494 cpsw_disable_irq(priv);
439 napi_schedule(&priv->napi); 495 napi_schedule(&priv->napi);
496 } else {
497 priv = cpsw_get_slave_priv(priv, 1);
498 if (likely(priv) && likely(netif_running(priv->ndev))) {
499 cpsw_intr_disable(priv);
500 cpsw_disable_irq(priv);
501 napi_schedule(&priv->napi);
502 }
440 } 503 }
441 return IRQ_HANDLED; 504 return IRQ_HANDLED;
442} 505}
443 506
444static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
445{
446 if (priv->host_port == 0)
447 return slave_num + 1;
448 else
449 return slave_num;
450}
451
452static int cpsw_poll(struct napi_struct *napi, int budget) 507static int cpsw_poll(struct napi_struct *napi, int budget)
453{ 508{
454 struct cpsw_priv *priv = napi_to_priv(napi); 509 struct cpsw_priv *priv = napi_to_priv(napi);
@@ -566,6 +621,54 @@ static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
566 leader + strlen(name), val); 621 leader + strlen(name), val);
567} 622}
568 623
624static int cpsw_common_res_usage_state(struct cpsw_priv *priv)
625{
626 u32 i;
627 u32 usage_count = 0;
628
629 if (!priv->data.dual_emac)
630 return 0;
631
632 for (i = 0; i < priv->data.slaves; i++)
633 if (priv->slaves[i].open_stat)
634 usage_count++;
635
636 return usage_count;
637}
638
639static inline int cpsw_tx_packet_submit(struct net_device *ndev,
640 struct cpsw_priv *priv, struct sk_buff *skb)
641{
642 if (!priv->data.dual_emac)
643 return cpdma_chan_submit(priv->txch, skb, skb->data,
644 skb->len, 0, GFP_KERNEL);
645
646 if (ndev == cpsw_get_slave_ndev(priv, 0))
647 return cpdma_chan_submit(priv->txch, skb, skb->data,
648 skb->len, 1, GFP_KERNEL);
649 else
650 return cpdma_chan_submit(priv->txch, skb, skb->data,
651 skb->len, 2, GFP_KERNEL);
652}
653
654static inline void cpsw_add_dual_emac_def_ale_entries(
655 struct cpsw_priv *priv, struct cpsw_slave *slave,
656 u32 slave_port)
657{
658 u32 port_mask = 1 << slave_port | 1 << priv->host_port;
659
660 if (priv->version == CPSW_VERSION_1)
661 slave_write(slave, slave->port_vlan, CPSW1_PORT_VLAN);
662 else
663 slave_write(slave, slave->port_vlan, CPSW2_PORT_VLAN);
664 cpsw_ale_add_vlan(priv->ale, slave->port_vlan, port_mask,
665 port_mask, port_mask, 0);
666 cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
667 port_mask, ALE_VLAN, slave->port_vlan, 0);
668 cpsw_ale_add_ucast(priv->ale, priv->mac_addr,
669 priv->host_port, ALE_VLAN, slave->port_vlan);
670}
671
569static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) 672static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
570{ 673{
571 char name[32]; 674 char name[32];
@@ -595,8 +698,11 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
595 698
596 slave_port = cpsw_get_slave_port(priv, slave->slave_num); 699 slave_port = cpsw_get_slave_port(priv, slave->slave_num);
597 700
598 cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 701 if (priv->data.dual_emac)
599 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); 702 cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
703 else
704 cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
705 1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
600 706
601 slave->phy = phy_connect(priv->ndev, slave->data->phy_id, 707 slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
602 &cpsw_adjust_link, slave->data->phy_if); 708 &cpsw_adjust_link, slave->data->phy_if);
@@ -634,6 +740,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
634static void cpsw_init_host_port(struct cpsw_priv *priv) 740static void cpsw_init_host_port(struct cpsw_priv *priv)
635{ 741{
636 u32 control_reg; 742 u32 control_reg;
743 u32 fifo_mode;
637 744
638 /* soft reset the controller and initialize ale */ 745 /* soft reset the controller and initialize ale */
639 soft_reset("cpsw", &priv->regs->soft_reset); 746 soft_reset("cpsw", &priv->regs->soft_reset);
@@ -645,6 +752,9 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
645 control_reg = readl(&priv->regs->control); 752 control_reg = readl(&priv->regs->control);
646 control_reg |= CPSW_VLAN_AWARE; 753 control_reg |= CPSW_VLAN_AWARE;
647 writel(control_reg, &priv->regs->control); 754 writel(control_reg, &priv->regs->control);
755 fifo_mode = (priv->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE :
756 CPSW_FIFO_NORMAL_MODE;
757 writel(fifo_mode, &priv->host_port_regs->tx_in_ctl);
648 758
649 /* setup host port priority mapping */ 759 /* setup host port priority mapping */
650 __raw_writel(CPDMA_TX_PRIORITY_MAP, 760 __raw_writel(CPDMA_TX_PRIORITY_MAP,
@@ -654,9 +764,12 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
654 cpsw_ale_control_set(priv->ale, priv->host_port, 764 cpsw_ale_control_set(priv->ale, priv->host_port,
655 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 765 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
656 766
657 cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port, 0, 0); 767 if (!priv->data.dual_emac) {
658 cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 768 cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port,
659 1 << priv->host_port, 0, 0, ALE_MCAST_FWD_2); 769 0, 0);
770 cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
771 1 << priv->host_port, 0, 0, ALE_MCAST_FWD_2);
772 }
660} 773}
661 774
662static int cpsw_ndo_open(struct net_device *ndev) 775static int cpsw_ndo_open(struct net_device *ndev)
@@ -665,7 +778,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
665 int i, ret; 778 int i, ret;
666 u32 reg; 779 u32 reg;
667 780
668 cpsw_intr_disable(priv); 781 if (!cpsw_common_res_usage_state(priv))
782 cpsw_intr_disable(priv);
669 netif_carrier_off(ndev); 783 netif_carrier_off(ndev);
670 784
671 pm_runtime_get_sync(&priv->pdev->dev); 785 pm_runtime_get_sync(&priv->pdev->dev);
@@ -677,46 +791,54 @@ static int cpsw_ndo_open(struct net_device *ndev)
677 CPSW_RTL_VERSION(reg)); 791 CPSW_RTL_VERSION(reg));
678 792
679 /* initialize host and slave ports */ 793 /* initialize host and slave ports */
680 cpsw_init_host_port(priv); 794 if (!cpsw_common_res_usage_state(priv))
795 cpsw_init_host_port(priv);
681 for_each_slave(priv, cpsw_slave_open, priv); 796 for_each_slave(priv, cpsw_slave_open, priv);
682 797
683 /* Add default VLAN */ 798 /* Add default VLAN */
684 cpsw_add_default_vlan(priv); 799 if (!priv->data.dual_emac)
800 cpsw_add_default_vlan(priv);
685 801
686 /* setup tx dma to fixed prio and zero offset */ 802 if (!cpsw_common_res_usage_state(priv)) {
687 cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, 1); 803 /* setup tx dma to fixed prio and zero offset */
688 cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0); 804 cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, 1);
805 cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0);
689 806
690 /* disable priority elevation and enable statistics on all ports */ 807 /* disable priority elevation */
691 __raw_writel(0, &priv->regs->ptype); 808 __raw_writel(0, &priv->regs->ptype);
692 809
693 /* enable statistics collection only on the host port */ 810 /* enable statistics collection only on all ports */
694 __raw_writel(0x7, &priv->regs->stat_port_en); 811 __raw_writel(0x7, &priv->regs->stat_port_en);
695 812
696 if (WARN_ON(!priv->data.rx_descs)) 813 if (WARN_ON(!priv->data.rx_descs))
697 priv->data.rx_descs = 128; 814 priv->data.rx_descs = 128;
698 815
699 for (i = 0; i < priv->data.rx_descs; i++) { 816 for (i = 0; i < priv->data.rx_descs; i++) {
700 struct sk_buff *skb; 817 struct sk_buff *skb;
701 818
702 ret = -ENOMEM; 819 ret = -ENOMEM;
703 skb = netdev_alloc_skb_ip_align(priv->ndev, 820 skb = netdev_alloc_skb_ip_align(priv->ndev,
704 priv->rx_packet_max); 821 priv->rx_packet_max);
705 if (!skb) 822 if (!skb)
706 break; 823 break;
707 ret = cpdma_chan_submit(priv->rxch, skb, skb->data, 824 ret = cpdma_chan_submit(priv->rxch, skb, skb->data,
708 skb_tailroom(skb), 0, GFP_KERNEL); 825 skb_tailroom(skb), 0, GFP_KERNEL);
709 if (WARN_ON(ret < 0)) 826 if (WARN_ON(ret < 0))
710 break; 827 break;
828 }
829 /* continue even if we didn't manage to submit all
830 * receive descs
831 */
832 cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
711 } 833 }
712 /* continue even if we didn't manage to submit all receive descs */
713 cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
714 834
715 cpdma_ctlr_start(priv->dma); 835 cpdma_ctlr_start(priv->dma);
716 cpsw_intr_enable(priv); 836 cpsw_intr_enable(priv);
717 napi_enable(&priv->napi); 837 napi_enable(&priv->napi);
718 cpdma_ctlr_eoi(priv->dma); 838 cpdma_ctlr_eoi(priv->dma);
719 839
840 if (priv->data.dual_emac)
841 priv->slaves[priv->emac_port].open_stat = true;
720 return 0; 842 return 0;
721} 843}
722 844
@@ -737,12 +859,17 @@ static int cpsw_ndo_stop(struct net_device *ndev)
737 netif_stop_queue(priv->ndev); 859 netif_stop_queue(priv->ndev);
738 napi_disable(&priv->napi); 860 napi_disable(&priv->napi);
739 netif_carrier_off(priv->ndev); 861 netif_carrier_off(priv->ndev);
740 cpsw_intr_disable(priv); 862
741 cpdma_ctlr_int_ctrl(priv->dma, false); 863 if (cpsw_common_res_usage_state(priv) <= 1) {
742 cpdma_ctlr_stop(priv->dma); 864 cpsw_intr_disable(priv);
743 cpsw_ale_stop(priv->ale); 865 cpdma_ctlr_int_ctrl(priv->dma, false);
866 cpdma_ctlr_stop(priv->dma);
867 cpsw_ale_stop(priv->ale);
868 }
744 for_each_slave(priv, cpsw_slave_stop, priv); 869 for_each_slave(priv, cpsw_slave_stop, priv);
745 pm_runtime_put_sync(&priv->pdev->dev); 870 pm_runtime_put_sync(&priv->pdev->dev);
871 if (priv->data.dual_emac)
872 priv->slaves[priv->emac_port].open_stat = false;
746 return 0; 873 return 0;
747} 874}
748 875
@@ -766,8 +893,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
766 893
767 skb_tx_timestamp(skb); 894 skb_tx_timestamp(skb);
768 895
769 ret = cpdma_chan_submit(priv->txch, skb, skb->data, 896 ret = cpsw_tx_packet_submit(ndev, priv, skb);
770 skb->len, 0, GFP_KERNEL);
771 if (unlikely(ret != 0)) { 897 if (unlikely(ret != 0)) {
772 cpsw_err(priv, tx_err, "desc submit failed\n"); 898 cpsw_err(priv, tx_err, "desc submit failed\n");
773 goto fail; 899 goto fail;
@@ -836,9 +962,14 @@ static void cpsw_hwtstamp_v1(struct cpsw_priv *priv)
836 962
837static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) 963static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
838{ 964{
839 struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave]; 965 struct cpsw_slave *slave;
840 u32 ctrl, mtype; 966 u32 ctrl, mtype;
841 967
968 if (priv->data.dual_emac)
969 slave = &priv->slaves[priv->emac_port];
970 else
971 slave = &priv->slaves[priv->data.cpts_active_slave];
972
842 ctrl = slave_read(slave, CPSW2_CONTROL); 973 ctrl = slave_read(slave, CPSW2_CONTROL);
843 ctrl &= ~CTRL_ALL_TS_MASK; 974 ctrl &= ~CTRL_ALL_TS_MASK;
844 975
@@ -1124,6 +1255,7 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
1124 slave->data = data; 1255 slave->data = data;
1125 slave->regs = regs + slave_reg_ofs; 1256 slave->regs = regs + slave_reg_ofs;
1126 slave->sliver = regs + sliver_reg_ofs; 1257 slave->sliver = regs + sliver_reg_ofs;
1258 slave->port_vlan = data->dual_emac_res_vlan;
1127} 1259}
1128 1260
1129static int cpsw_probe_dt(struct cpsw_platform_data *data, 1261static int cpsw_probe_dt(struct cpsw_platform_data *data,
@@ -1204,6 +1336,9 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1204 } 1336 }
1205 data->mac_control = prop; 1337 data->mac_control = prop;
1206 1338
1339 if (!of_property_read_u32(node, "dual_emac", &prop))
1340 data->dual_emac = prop;
1341
1207 /* 1342 /*
1208 * Populate all the child nodes here... 1343 * Populate all the child nodes here...
1209 */ 1344 */
@@ -1237,6 +1372,18 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1237 if (mac_addr) 1372 if (mac_addr)
1238 memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); 1373 memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
1239 1374
1375 if (data->dual_emac) {
1376 if (of_property_read_u32(node, "dual_emac_res_vlan",
1377 &prop)) {
1378 pr_err("Missing dual_emac_res_vlan in DT.\n");
1379 slave_data->dual_emac_res_vlan = i+1;
1380 pr_err("Using %d as Reserved VLAN for %d slave\n",
1381 slave_data->dual_emac_res_vlan, i);
1382 } else {
1383 slave_data->dual_emac_res_vlan = prop;
1384 }
1385 }
1386
1240 i++; 1387 i++;
1241 } 1388 }
1242 1389
@@ -1247,6 +1394,79 @@ error_ret:
1247 return ret; 1394 return ret;
1248} 1395}
1249 1396
1397static int cpsw_probe_dual_emac(struct platform_device *pdev,
1398 struct cpsw_priv *priv)
1399{
1400 struct cpsw_platform_data *data = &priv->data;
1401 struct net_device *ndev;
1402 struct cpsw_priv *priv_sl2;
1403 int ret = 0, i;
1404
1405 ndev = alloc_etherdev(sizeof(struct cpsw_priv));
1406 if (!ndev) {
1407 pr_err("cpsw: error allocating net_device\n");
1408 return -ENOMEM;
1409 }
1410
1411 priv_sl2 = netdev_priv(ndev);
1412 spin_lock_init(&priv_sl2->lock);
1413 priv_sl2->data = *data;
1414 priv_sl2->pdev = pdev;
1415 priv_sl2->ndev = ndev;
1416 priv_sl2->dev = &ndev->dev;
1417 priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
1418 priv_sl2->rx_packet_max = max(rx_packet_max, 128);
1419
1420 if (is_valid_ether_addr(data->slave_data[1].mac_addr)) {
1421 memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr,
1422 ETH_ALEN);
1423 pr_info("cpsw: Detected MACID = %pM\n", priv_sl2->mac_addr);
1424 } else {
1425 random_ether_addr(priv_sl2->mac_addr);
1426 pr_info("cpsw: Random MACID = %pM\n", priv_sl2->mac_addr);
1427 }
1428 memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN);
1429
1430 priv_sl2->slaves = priv->slaves;
1431 priv_sl2->clk = priv->clk;
1432
1433 priv_sl2->cpsw_res = priv->cpsw_res;
1434 priv_sl2->regs = priv->regs;
1435 priv_sl2->host_port = priv->host_port;
1436 priv_sl2->host_port_regs = priv->host_port_regs;
1437 priv_sl2->wr_regs = priv->wr_regs;
1438 priv_sl2->dma = priv->dma;
1439 priv_sl2->txch = priv->txch;
1440 priv_sl2->rxch = priv->rxch;
1441 priv_sl2->ale = priv->ale;
1442 priv_sl2->emac_port = 1;
1443 priv->slaves[1].ndev = ndev;
1444 priv_sl2->cpts = priv->cpts;
1445 priv_sl2->version = priv->version;
1446
1447 for (i = 0; i < priv->num_irqs; i++) {
1448 priv_sl2->irqs_table[i] = priv->irqs_table[i];
1449 priv_sl2->num_irqs = priv->num_irqs;
1450 }
1451
1452 ndev->features |= NETIF_F_HW_VLAN_FILTER;
1453
1454 ndev->netdev_ops = &cpsw_netdev_ops;
1455 SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
1456 netif_napi_add(ndev, &priv_sl2->napi, cpsw_poll, CPSW_POLL_WEIGHT);
1457
1458 /* register the network device */
1459 SET_NETDEV_DEV(ndev, &pdev->dev);
1460 ret = register_netdev(ndev);
1461 if (ret) {
1462 pr_err("cpsw: error registering net device\n");
1463 free_netdev(ndev);
1464 ret = -ENODEV;
1465 }
1466
1467 return ret;
1468}
1469
1250static int cpsw_probe(struct platform_device *pdev) 1470static int cpsw_probe(struct platform_device *pdev)
1251{ 1471{
1252 struct cpsw_platform_data *data = pdev->dev.platform_data; 1472 struct cpsw_platform_data *data = pdev->dev.platform_data;
@@ -1310,6 +1530,9 @@ static int cpsw_probe(struct platform_device *pdev)
1310 for (i = 0; i < data->slaves; i++) 1530 for (i = 0; i < data->slaves; i++)
1311 priv->slaves[i].slave_num = i; 1531 priv->slaves[i].slave_num = i;
1312 1532
1533 priv->slaves[0].ndev = ndev;
1534 priv->emac_port = 0;
1535
1313 priv->clk = clk_get(&pdev->dev, "fck"); 1536 priv->clk = clk_get(&pdev->dev, "fck");
1314 if (IS_ERR(priv->clk)) { 1537 if (IS_ERR(priv->clk)) {
1315 dev_err(&pdev->dev, "fck is not found\n"); 1538 dev_err(&pdev->dev, "fck is not found\n");
@@ -1484,6 +1707,14 @@ static int cpsw_probe(struct platform_device *pdev)
1484 cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n", 1707 cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n",
1485 priv->cpsw_res->start, ndev->irq); 1708 priv->cpsw_res->start, ndev->irq);
1486 1709
1710 if (priv->data.dual_emac) {
1711 ret = cpsw_probe_dual_emac(pdev, priv);
1712 if (ret) {
1713 cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
1714 goto clean_irq_ret;
1715 }
1716 }
1717
1487 return 0; 1718 return 0;
1488 1719
1489clean_irq_ret: 1720clean_irq_ret:
diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h
index e962cfd552e3..798fb80b024b 100644
--- a/include/linux/platform_data/cpsw.h
+++ b/include/linux/platform_data/cpsw.h
@@ -21,6 +21,8 @@ struct cpsw_slave_data {
21 char phy_id[MII_BUS_ID_SIZE]; 21 char phy_id[MII_BUS_ID_SIZE];
22 int phy_if; 22 int phy_if;
23 u8 mac_addr[ETH_ALEN]; 23 u8 mac_addr[ETH_ALEN];
24 u16 dual_emac_res_vlan; /* Reserved VLAN for DualEMAC */
25
24}; 26};
25 27
26struct cpsw_platform_data { 28struct cpsw_platform_data {
@@ -36,6 +38,7 @@ struct cpsw_platform_data {
36 u32 rx_descs; /* Number of Rx Descriptios */ 38 u32 rx_descs; /* Number of Rx Descriptios */
37 u32 mac_control; /* Mac control register */ 39 u32 mac_control; /* Mac control register */
38 u16 default_vlan; /* Def VLAN for ALE lookup in VLAN aware mode*/ 40 u16 default_vlan; /* Def VLAN for ALE lookup in VLAN aware mode*/
41 bool dual_emac; /* Enable Dual EMAC mode */
39}; 42};
40 43
41#endif /* __CPSW_H__ */ 44#endif /* __CPSW_H__ */