octeontx2-af: CGX LMAC link bringup and cleanups
cover octeontx2-af: CGX LMAC link bringup and cleanups
From: Linu Cherian <[email protected]>
Patch 1: Code cleanup
Patch 2: Adds support for an unhandled hardware configuration Patch 3: Preparatory patch for enabling cgx lmac links Patch 4: Support for enabling cgx lmac links
Linu Cherian (4):
octeontx2-af: Misc cleanups in cgx driver
octeontx2-af: Handle non-contiguous CGX LMAC interfaces
octeontx2-af: Unregister cgx event callbacks gracefully
octeontx2-af: Bringup CGX LMAC links by default
.../net/ethernet/marvell/octeontx2/af/cgx.c | 108 ++++++++++++++++-- .../net/ethernet/marvell/octeontx2/af/cgx.h | 34 +++--- .../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 2 - .../net/ethernet/marvell/octeontx2/af/rvu.c | 26 +++-- .../net/ethernet/marvell/octeontx2/af/rvu.h | 6 +- .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 97 ++++++++++++---- .../ethernet/marvell/octeontx2/af/rvu_nix.c | 6 +- 7 files changed, 214 insertions(+), 65 deletions(-)
Signature · 1 line
2.19.1
PATCH 1/4 octeontx2-af: Misc cleanups in cgx driver
From: Linu Cherian <[email protected]>
* Do CGX init before NIX init
This would add consistency in NIX code that depends on cgx ports
* Few other misc cleanups
- rvu_cgx_probe renamed as rvu_cgx_init for consistency
- rvu_cgx_exit wrapper added to take care of the exit path
- Added error check on cgx_lmac_event_handler_init
- Minor cleanups in cgx.h related to tab alignment
- Removed redundant ids from enum cgx_cmd_id
--- .../net/ethernet/marvell/octeontx2/af/cgx.h | 28 +++++++++---------- .../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 2 -- .../net/ethernet/marvell/octeontx2/af/rvu.c | 26 +++++++++-------- .../net/ethernet/marvell/octeontx2/af/rvu.h | 4 +-- .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 27 ++++++++++++------ 5 files changed, 50 insertions(+), 37 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.h +14 -14
@@ -27,34 +27,34 @@/* Registers */ #define CGXX_CMRX_CFG 0x00 -#define CMR_EN BIT_ULL(55) -#define DATA_PKT_TX_EN BIT_ULL(53) -#define DATA_PKT_RX_EN BIT_ULL(54) -#define CGX_LMAC_TYPE_SHIFT 40 -#define CGX_LMAC_TYPE_MASK 0xF +#define CMR_EN BIT_ULL(55) +#define DATA_PKT_TX_EN BIT_ULL(53) +#define DATA_PKT_RX_EN BIT_ULL(54) +#define CGX_LMAC_TYPE_SHIFT 40 +#define CGX_LMAC_TYPE_MASK 0xF#define CGXX_CMRX_INT 0x040 -#define FW_CGX_INT BIT_ULL(1) +#define FW_CGX_INT BIT_ULL(1)#define CGXX_CMRX_INT_ENA_W1S 0x058#define CGXX_CMRX_RX_ID_MAP 0x060#define CGXX_CMRX_RX_STAT0 0x070#define CGXX_CMRX_RX_LMACS 0x128#define CGXX_CMRX_RX_DMAC_CTL0 0x1F8 -#define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3) -#define CGX_DMAC_CAM_ACCEPT BIT_ULL(3) -#define CGX_DMAC_MCAST_MODE BIT_ULL(1) -#define CGX_DMAC_BCAST_MODE BIT_ULL(0) +#define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3) +#define CGX_DMAC_CAM_ACCEPT BIT_ULL(3) +#define CGX_DMAC_MCAST_MODE BIT_ULL(1) +#define CGX_DMAC_BCAST_MODE BIT_ULL(0)#define CGXX_CMRX_RX_DMAC_CAM0 0x200 -#define CGX_DMAC_CAM_ADDR_ENABLE BIT_ULL(48) +#define CGX_DMAC_CAM_ADDR_ENABLE BIT_ULL(48)#define CGXX_CMRX_RX_DMAC_CAM1 0x400 -#define CGX_RX_DMAC_ADR_MASK GENMASK_ULL(47, 0) +#define CGX_RX_DMAC_ADR_MASK GENMASK_ULL(47, 0)#define CGXX_CMRX_TX_STAT0 0x700#define CGXX_SCRATCH0_REG 0x1050#define CGXX_SCRATCH1_REG 0x1058#define CGX_CONST 0x2000#define CGXX_SPUX_CONTROL1 0x10000 -#define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14) +#define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14)#define CGXX_GMP_PCS_MRX_CTL 0x30000 -#define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14) +#define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14)#define CGX_COMMAND_REG CGXX_SCRATCH1_REG#define CGX_EVENT_REG CGXX_SCRATCH0_REG
drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h +0 -2
@@ -78,8 +78,6 @@ enum cgx_cmd_id {CGX_CMD_LINK_STATE_CHANGE ,CGX_CMD_MODE_CHANGE ,/* hot plug support */ CGX_CMD_INTF_SHUTDOWN, -CGX_CMD_IRQ_ENABLE , - CGX_CMD_IRQ_DISABLE, };/* async event ids */
drivers/net/ethernet/marvell/octeontx2/af/rvu.c +15 -11
@@ -811,17 +811,26 @@ static int rvu_setup_hw_resources(struct rvu *rvu) err =rvu_npc_init (rvu);if (err) -return err; + goto exit; + + err =rvu_cgx_init (rvu); +if (err) + goto exit; err =rvu_npa_init (rvu);if (err) -return err; + goto cgx_err; err =rvu_nix_init (rvu);if (err) -return err; + goto cgx_err;return 0 ; + +cgx_err: +rvu_cgx_exit (rvu); +exit: +return err; }/* NPA and NIX admin queue APIs */
@@ -2419,13 +2428,9 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (err) goto err_hwsetup; - err =rvu_cgx_probe (rvu); -if (err) - goto err_mbox; - err =rvu_flr_init (rvu);if (err) - goto err_cgx; + goto err_mbox; err =rvu_register_interrupts (rvu);if (err)
@@ -2441,11 +2446,10 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)rvu_unregister_interrupts (rvu); err_flr:rvu_flr_wq_destroy (rvu); -err_cgx: -rvu_cgx_wq_destroy (rvu); err_mbox:rvu_mbox_destroy (&rvu->afpf_wq_info); err_hwsetup: +rvu_cgx_exit (rvu);rvu_reset_all_blocks (rvu);rvu_free_hw_resources (rvu); err_release_regions:
@@ -2465,7 +2469,7 @@ static void rvu_remove(struct pci_dev *pdev)rvu_unregister_interrupts (rvu);rvu_flr_wq_destroy (rvu); -rvu_cgx_wq_destroy (rvu); +rvu_cgx_exit (rvu);rvu_mbox_destroy (&rvu->afpf_wq_info);rvu_disable_sriov (rvu);rvu_reset_all_blocks (rvu);
drivers/net/ethernet/marvell/octeontx2/af/rvu.h +2 -2
@@ -316,8 +316,8 @@ static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id) *lmac_id = (map &0xF ); } -int rvu_cgx_probe (struct rvu *rvu); -void rvu_cgx_wq_destroy (struct rvu *rvu); +int rvu_cgx_init (struct rvu *rvu); +int rvu_cgx_exit (struct rvu *rvu);void *rvu_cgx_pdata (u8 cgx_id,struct rvu *rvu);int rvu_cgx_config_rxtx (struct rvu *rvu,u16 pcifunc,bool start); int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +19 -8
@@ -216,7 +216,7 @@ static void cgx_evhandler_task(struct work_struct *work) }while (1 ); } -static void cgx_lmac_event_handler_init (struct rvu *rvu) +static int cgx_lmac_event_handler_init (struct rvu *rvu) {struct cgx_event_cb cb;int cgx, lmac, err;
@@ -228,7 +228,7 @@ static void cgx_lmac_event_handler_init(struct rvu *rvu) rvu->cgx_evh_wq =alloc_workqueue ("rvu_evh_wq" ,0 ,0 );if (!rvu->cgx_evh_wq) {dev_err (rvu->dev,"alloc workqueue failed" ); -return ; +return -ENOMEM ; } cb.notify_link_chg = cgx_lmac_postevent;/* link change call back */
@@ -244,9 +244,11 @@ static void cgx_lmac_event_handler_init(struct rvu *rvu) cgx, lmac); } } + +return 0 ; } -void rvu_cgx_wq_destroy (struct rvu *rvu) +static void rvu_cgx_wq_destroy (struct rvu *rvu) {if (rvu->cgx_evh_wq) {flush_workqueue (rvu->cgx_evh_wq);
@@ -255,9 +257,9 @@ void rvu_cgx_wq_destroy(struct rvu *rvu) } } -int rvu_cgx_probe (struct rvu *rvu) +int rvu_cgx_init (struct rvu *rvu) { -int i, err; +int cgx, err;/* find available cgx ports */ rvu->cgx_cnt =cgx_get_cgx_cnt ();
@@ -272,8 +274,8 @@ int rvu_cgx_probe(struct rvu *rvu)return -ENOMEM ;/* Initialize the cgxdata table */ -for (i =0 ; i < rvu->cgx_cnt; i++) - rvu->cgx_idmap[i] =cgx_get_pdata (i); +for (cgx =0 ; cgx < rvu->cgx_cnt; cgx++) + rvu->cgx_idmap[cgx] =cgx_get_pdata (cgx);/* Map CGX LMAC interfaces to RVU PFs */ err =rvu_map_cgx_lmac_pf (rvu);
@@ -281,7 +283,16 @@ int rvu_cgx_probe(struct rvu *rvu)return err;/* Register for CGX events */ -cgx_lmac_event_handler_init (rvu); + err =cgx_lmac_event_handler_init (rvu); +if (err) +return err; + +return 0 ; +} + +int rvu_cgx_exit (struct rvu *rvu) +{ +rvu_cgx_wq_destroy (rvu);return 0 ; }
Signature · 1 line
2.19.1
PATCH 2/4 octeontx2-af: Handle non-contiguous CGX LMAC interfaces
In reply to Linu CherianFrom: Linu Cherian <[email protected]>
For this, cgx_id(struct cgx) definition has been changed to reflect cgx port id instead of device instance id.
Now cgx_id can be directly used as channel offset for NPC configuration. Assumptions on contiguous cgx port ids has been removed from nix_calibrate_x2p as well.
As a side effect, allocation of conversion tables that were based on cgx count are changed to cgx port id max value. Tables would return NULL for invalid cgx ports.
--- .../net/ethernet/marvell/octeontx2/af/cgx.c | 18 ++++++--- .../net/ethernet/marvell/octeontx2/af/cgx.h | 4 +- .../net/ethernet/marvell/octeontx2/af/rvu.h | 2 +- .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 38 ++++++++++--------- .../ethernet/marvell/octeontx2/af/rvu_nix.c | 6 ++- 5 files changed, 40 insertions(+), 28 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +12 -6
@@ -92,17 +92,21 @@ static inline struct lmac *lmac_pdata(u8 lmac_id, struct cgx *cgx)return cgx->lmac_idmap[lmac_id]; } -int cgx_get_cgx_cnt (void ) +int cgx_get_cgxcnt_max (void ) {struct cgx *cgx_dev; -int count =0 ; +int idmax = -ENODEV ;list_for_each_entry (cgx_dev, &cgx_list, cgx_list) - count++; +if (cgx_dev->cgx_id > idmax) + idmax = cgx_dev->cgx_id; -return count; +if (idmax <0 ) +return 0 ; + +return idmax +1 ; } -EXPORT_SYMBOL (cgx_get_cgx_cnt); +EXPORT_SYMBOL (cgx_get_cgxcnt_max);int cgx_get_lmac_cnt (void *cgxd) {
@@ -679,8 +683,10 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_release_regions; } + cgx->cgx_id = (pci_resource_start (pdev,PCI_CFG_REG_BAR_NUM ) >>24 ) + &CGX_ID_MASK ; +list_add (&cgx->cgx_list, &cgx_list); - cgx->cgx_id =cgx_get_cgx_cnt () -1 ;cgx_link_usertable_init ();
drivers/net/ethernet/marvell/octeontx2/af/cgx.h +2 -2
@@ -20,7 +20,7 @@/* PCI BAR nos */ #define PCI_CFG_REG_BAR_NUM 0 -#define MAX_CGX 3 +#define CGX_ID_MASK 0x7#define MAX_LMAC_PER_CGX 4#define CGX_FIFO_LEN 65536/* 64K for both Rx & Tx */ #define CGX_OFFSET (x) ((x) * MAX_LMAC_PER_CGX)
@@ -95,7 +95,7 @@ struct cgx_event_cb {extern struct pci_driver cgx_driver; -int cgx_get_cgx_cnt (void ); +int cgx_get_cgxcnt_max (void );int cgx_get_lmac_cnt (void *cgxd);void *cgx_get_pdata (int cgx_id);int cgx_set_pkind (void *cgxd,u8 lmac_id,int pkind);
drivers/net/ethernet/marvell/octeontx2/af/rvu.h +1 -1
@@ -226,7 +226,7 @@ struct rvu {/* CGX */ #define PF_CGXMAP_BASE 1/* PF 0 is reserved for RVU PF */ u8 cgx_mapped_pfs; -u8 cgx_cnt;/* available cgx ports */ +u8 cgx_cnt_max;/* CGX port count max */ u8 *pf2cgxlmac_map;/* pf to cgx_lmac map */ u16 *cgxlmac2pf_map;/* bitmap of mapped pfs for * every cgx lmac port
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +21 -17
@@ -52,7 +52,7 @@ static inline u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id)void *rvu_cgx_pdata (u8 cgx_id,struct rvu *rvu) { -if (cgx_id >= rvu->cgx_cnt) +if (cgx_id >= rvu->cgx_cnt_max)return NULL ;return rvu->cgx_idmap[cgx_id];
@@ -61,38 +61,40 @@ void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu)static int rvu_map_cgx_lmac_pf (struct rvu *rvu) {struct npc_pkind *pkind = &rvu->hw->pkind; -int cgx_cnt = rvu->cgx_cnt; +int cgx_cnt_max = rvu->cgx_cnt_max;int cgx, lmac_cnt, lmac;int pf =PF_CGXMAP_BASE ;int size, free_pkind; -if (!cgx_cnt) +if (!cgx_cnt_max)return 0 ; -if (cgx_cnt >0xF ||MAX_LMAC_PER_CGX >0xF ) +if (cgx_cnt_max >0xF ||MAX_LMAC_PER_CGX >0xF )return -EINVAL ;/* Alloc map table * An additional entry is required since PF id starts from 1 and * hence entry at offset 0 is invalid. */ - size = (cgx_cnt *MAX_LMAC_PER_CGX +1 ) *sizeof (u8); - rvu->pf2cgxlmac_map =devm_kzalloc (rvu->dev, size,GFP_KERNEL ); + size = (cgx_cnt_max *MAX_LMAC_PER_CGX +1 ) *sizeof (u8); + rvu->pf2cgxlmac_map =devm_kmalloc (rvu->dev, size,GFP_KERNEL );if (!rvu->pf2cgxlmac_map)return -ENOMEM ; -/* Initialize offset 0 with an invalid cgx and lmac id */ - rvu->pf2cgxlmac_map[0 ] =0xFF ; +/* Initialize all entries with an invalid cgx and lmac id */ +memset (rvu->pf2cgxlmac_map,0xFF , size);/* Reverse map table */ rvu->cgxlmac2pf_map =devm_kzalloc (rvu->dev, - cgx_cnt *MAX_LMAC_PER_CGX *sizeof (u16), + cgx_cnt_max *MAX_LMAC_PER_CGX *sizeof (u16),GFP_KERNEL );if (!rvu->cgxlmac2pf_map)return -ENOMEM ; rvu->cgx_mapped_pfs =0 ; -for (cgx =0 ; cgx < cgx_cnt; cgx++) { +for (cgx =0 ; cgx < cgx_cnt_max; cgx++) { +if (!rvu_cgx_pdata (cgx, rvu)) +continue ; lmac_cnt =cgx_get_lmac_cnt (rvu_cgx_pdata (cgx, rvu));for (lmac =0 ; lmac < lmac_cnt; lmac++, pf++) { rvu->pf2cgxlmac_map[pf] =cgxlmac_id_to_bmap (cgx, lmac);
@@ -234,7 +236,7 @@ static int cgx_lmac_event_handler_init(struct rvu *rvu) cb.notify_link_chg = cgx_lmac_postevent;/* link change call back */ cb.data = rvu; -for (cgx =0 ; cgx < rvu->cgx_cnt; cgx++) { +for (cgx =0 ; cgx <= rvu->cgx_cnt_max; cgx++) { cgxd =rvu_cgx_pdata (cgx, rvu);for (lmac =0 ; lmac <cgx_get_lmac_cnt (cgxd); lmac++) { err =cgx_lmac_evh_register (&cb, cgxd, lmac);
@@ -261,20 +263,22 @@ int rvu_cgx_init(struct rvu *rvu) {int cgx, err; -/* find available cgx ports */ - rvu->cgx_cnt =cgx_get_cgx_cnt (); -if (!rvu->cgx_cnt) { +/* CGX port id starts from 0 and are not necessarily contiguous +* Hence we allocate resources based on the maximum port id value. +*/ + rvu->cgx_cnt_max =cgx_get_cgxcnt_max (); +if (!rvu->cgx_cnt_max) {dev_info (rvu->dev,"No CGX devices found!\n" );return -ENODEV ; } - rvu->cgx_idmap =devm_kzalloc (rvu->dev, rvu->cgx_cnt *sizeof (void *), -GFP_KERNEL ); + rvu->cgx_idmap =devm_kzalloc (rvu->dev, rvu->cgx_cnt_max * +sizeof (void *),GFP_KERNEL );if (!rvu->cgx_idmap)return -ENOMEM ;/* Initialize the cgxdata table */ -for (cgx =0 ; cgx < rvu->cgx_cnt; cgx++) +for (cgx =0 ; cgx < rvu->cgx_cnt_max; cgx++) rvu->cgx_idmap[cgx] =cgx_get_pdata (cgx);/* Map CGX LMAC interfaces to RVU PFs */
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +4 -2
@@ -2107,8 +2107,10 @@ static int nix_calibrate_x2p(struct rvu *rvu, int blkaddr) status =rvu_read64 (rvu, blkaddr,NIX_AF_STATUS );/* Check if CGX devices are ready */ -for (idx =0 ; idx <cgx_get_cgx_cnt (); idx++) { -if (status & (BIT_ULL (16 + idx))) +for (idx =0 ; idx < rvu->cgx_cnt_max; idx++) { +/* Skip when cgx port is not available */ +if (!rvu_cgx_pdata (idx, rvu) || + (status & (BIT_ULL (16 + idx))))continue ;dev_err (rvu->dev,"CGX%d didn't respond to NIX X2P calibration\n" , idx);
Signature · 1 line
2.19.1
PATCH 3/4 octeontx2-af: Unregister cgx event callbacks gracefully
In reply to Linu CherianFrom: Linu Cherian <[email protected]>
Added provision to unregister cgx event callbacks. This enables the exit path to ensure event callbacks are unregistered before workqueues get destroyed.
--- .../net/ethernet/marvell/octeontx2/af/cgx.c | 29 ++++++++++++++++++- .../net/ethernet/marvell/octeontx2/af/cgx.h | 1 + .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 14 +++++++++ 3 files changed, 43 insertions(+), 1 deletion(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +28 -1
@@ -31,6 +31,7 @@* @resp: command response * @link_info: link related information * @event_cb: callback for linkchange events +* @event_cb_lock: lock for serializing callback with unregister * @cmd_pend: flag set before new command is started * flag cleared after command response is received * @cgx: parent cgx port
@@ -43,6 +44,7 @@ struct lmac {u64 resp;struct cgx_link_user_info link_info;struct cgx_event_cb event_cb; +spinlock_t event_cb_lock;bool cmd_pend;struct cgx *cgx;u8 lmac_id;
@@ -449,6 +451,9 @@ static inline void cgx_link_change_handler(u64 lstat, lmac->link_info = event.link_uinfo; linfo = &lmac->link_info; +/* Ensure callback doesn't get unregistered until we finish it */ +spin_lock (&lmac->event_cb_lock); +if (!lmac->event_cb.notify_link_chg) {dev_dbg (dev,"cgx port %d:%d Link change handler null" , cgx->cgx_id, lmac->lmac_id);
@@ -459,11 +464,13 @@ static inline void cgx_link_change_handler(u64 lstat,dev_info (dev,"cgx port %d:%d Link is %s %d Mbps\n" , cgx->cgx_id, lmac->lmac_id, linfo->link_up ?"UP" :"DOWN" , linfo->speed); -return ; + goto err; }if (lmac->event_cb.notify_link_chg (&event, lmac->event_cb.data))dev_err (dev,"event notification failure\n" ); +err: +spin_unlock (&lmac->event_cb_lock); }static inline bool cgx_cmdresp_is_linkevent (u64 event)
@@ -552,6 +559,25 @@ int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id) }EXPORT_SYMBOL (cgx_lmac_evh_register); +int cgx_lmac_evh_unregister (void *cgxd,int lmac_id) +{ +struct lmac *lmac; +unsigned long flags; +struct cgx *cgx = cgxd; + + lmac =lmac_pdata (lmac_id, cgx); +if (!lmac) +return -ENODEV ; + +spin_lock_irqsave (&lmac->event_cb_lock, flags); + lmac->event_cb.notify_link_chg =NULL ; + lmac->event_cb.data =NULL ; +spin_unlock_irqrestore (&lmac->event_cb_lock, flags); + +return 0 ; +} +EXPORT_SYMBOL (cgx_lmac_evh_unregister); +static inline int cgx_fwi_read_version (u64 *resp,struct cgx *cgx) {u64 req =0 ;
@@ -606,6 +632,7 @@ static int cgx_lmac_init(struct cgx *cgx) lmac->cgx = cgx;init_waitqueue_head (&lmac->wq_cmd_cmplt);mutex_init (&lmac->cmd_lock); +spin_lock_init (&lmac->event_cb_lock); err =request_irq (pci_irq_vector (cgx->pdev,CGX_LMAC_FWI + i *9 ), cgx_fwi_event_handler,0 , lmac->name, lmac);
drivers/net/ethernet/marvell/octeontx2/af/cgx.h +1 -0
@@ -100,6 +100,7 @@ int cgx_get_lmac_cnt(void *cgxd);void *cgx_get_pdata (int cgx_id);int cgx_set_pkind (void *cgxd,u8 lmac_id,int pkind);int cgx_lmac_evh_register (struct cgx_event_cb *cb,void *cgxd,int lmac_id); +int cgx_lmac_evh_unregister (void *cgxd,int lmac_id);int cgx_get_tx_stats (void *cgxd,int lmac_id,int idx,u64 *tx_stat);int cgx_get_rx_stats (void *cgxd,int lmac_id,int idx,u64 *rx_stat);int cgx_lmac_rx_tx_enable (void *cgxd,int lmac_id,bool enable);
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +14 -0
@@ -296,6 +296,20 @@ int rvu_cgx_init(struct rvu *rvu)int rvu_cgx_exit (struct rvu *rvu) { +int cgx, lmac; +void *cgxd; + +for (cgx =0 ; cgx <= rvu->cgx_cnt_max; cgx++) { + cgxd =rvu_cgx_pdata (cgx, rvu); +if (!cgxd) +continue ; +for (lmac =0 ; lmac <cgx_get_lmac_cnt (cgxd); lmac++) +cgx_lmac_evh_unregister (cgxd, lmac); + } + +/* Ensure event handler unregister is completed */ +mb (); +rvu_cgx_wq_destroy (rvu);return 0 ; }
Signature · 1 line
2.19.1
PATCH 4/4 octeontx2-af: Bringup CGX LMAC links by default
In reply to Linu CherianFrom: Linu Cherian <[email protected]>
- Added new CGX firmware interface API for sending link up/down commands
- Do link up for cgx lmac ports by default at the time of CGX driver probe. Since cgx link up in driver probe affects the Linux boot time, linkup procedure is kept threaded using workqueues.
For this, a new cgx API cgx_lmac_linkup_start has been added.
--- .../net/ethernet/marvell/octeontx2/af/cgx.c | 61 +++++++++++++++++++ .../net/ethernet/marvell/octeontx2/af/cgx.h | 1 + .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 20 ++++++ 3 files changed, 82 insertions(+)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +61 -0
@@ -57,6 +57,8 @@ struct cgx {u8 cgx_id;u8 lmac_count;struct lmac *lmac_idmap[MAX_LMAC_PER_CGX ]; +struct work_struct cgx_cmd_work; +struct workqueue_struct *cgx_cmd_workq;struct list_head cgx_list; };
@@ -68,6 +70,9 @@ static u32 cgx_speed_mbps[CGX_LINK_SPEED_MAX];/* Convert firmware lmac type encoding to string */ static char *cgx_lmactype_string[LMAC_MODE_MAX ]; +/* CGX PHY management internal APIs */ +static int cgx_fwi_link_change (struct cgx *cgx,int lmac_id,bool en); +/* Supported devices */ static const struct pci_device_id cgx_id_table[] = { {PCI_DEVICE (PCI_VENDOR_ID_CAVIUM ,PCI_DEVID_OCTEONTX2_CGX ) },
@@ -578,6 +583,19 @@ int cgx_lmac_evh_unregister(void *cgxd, int lmac_id) }EXPORT_SYMBOL (cgx_lmac_evh_unregister); +static int cgx_fwi_link_change (struct cgx *cgx,int lmac_id,bool enable) +{ +u64 req =0 ; +u64 resp; + +if (enable) + req =FIELD_SET (CMDREG_ID ,CGX_CMD_LINK_BRING_UP , req); +else + req =FIELD_SET (CMDREG_ID ,CGX_CMD_LINK_BRING_DOWN , req); + +return cgx_fwi_cmd_generic (req, &resp, cgx, lmac_id); +} +static inline int cgx_fwi_read_version (u64 *resp,struct cgx *cgx) {u64 req =0 ;
@@ -611,6 +629,34 @@ static int cgx_lmac_verify_fwi_version(struct cgx *cgx)return 0 ; } +static void cgx_lmac_linkup_work (struct work_struct *work) +{ + struct cgx *cgx = container_of(work, struct cgx, cgx_cmd_work); +struct device *dev = &cgx->pdev->dev; +int i, err; + +/* Do Link up for all the lmacs */ +for (i =0 ; i < cgx->lmac_count; i++) { + err =cgx_fwi_link_change (cgx, i, true); +if (err) +dev_info (dev,"cgx port %d:%d Link up command failed\n" , + cgx->cgx_id, i); + } +} + +int cgx_lmac_linkup_start (void *cgxd) +{ +struct cgx *cgx = cgxd; + +if (!cgx) +return -ENODEV ; + +queue_work (cgx->cgx_cmd_workq, &cgx->cgx_cmd_work); + +return 0 ; +} +EXPORT_SYMBOL (cgx_lmac_linkup_start); +static int cgx_lmac_init (struct cgx *cgx) {struct lmac *lmac;
@@ -655,6 +701,12 @@ static int cgx_lmac_exit(struct cgx *cgx)struct lmac *lmac;int i; +if (cgx->cgx_cmd_workq) { +flush_workqueue (cgx->cgx_cmd_workq); +destroy_workqueue (cgx->cgx_cmd_workq); + cgx->cgx_cmd_workq =NULL ; + } +/* Free all lmac related resources */ for (i =0 ; i < cgx->lmac_count; i++) { lmac = cgx->lmac_idmap[i];
@@ -713,6 +765,15 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id) cgx->cgx_id = (pci_resource_start (pdev,PCI_CFG_REG_BAR_NUM ) >>24 ) &CGX_ID_MASK ; +/* init wq for processing linkup requests */ +INIT_WORK (&cgx->cgx_cmd_work, cgx_lmac_linkup_work); + cgx->cgx_cmd_workq =alloc_workqueue ("cgx_cmd_workq" ,0 ,0 ); +if (!cgx->cgx_cmd_workq) { +dev_err (dev,"alloc workqueue failed for cgx cmd" ); + err = -ENOMEM ; + goto err_release_regions; + } +list_add (&cgx->cgx_list, &cgx_list);cgx_link_usertable_init ();
drivers/net/ethernet/marvell/octeontx2/af/cgx.h +1 -0
@@ -110,4 +110,5 @@ void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);int cgx_lmac_internal_loopback (void *cgxd,int lmac_id,bool enable);int cgx_get_link_info (void *cgxd,int lmac_id,struct cgx_link_user_info *linfo); +int cgx_lmac_linkup_start (void *cgxd);#endif /* CGX_H */
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +20 -0
@@ -238,6 +238,8 @@ static int cgx_lmac_event_handler_init(struct rvu *rvu)for (cgx =0 ; cgx <= rvu->cgx_cnt_max; cgx++) { cgxd =rvu_cgx_pdata (cgx, rvu); +if (!cgxd) +continue ;for (lmac =0 ; lmac <cgx_get_lmac_cnt (cgxd); lmac++) { err =cgx_lmac_evh_register (&cb, cgxd, lmac);if (err)
@@ -262,6 +264,7 @@ static void rvu_cgx_wq_destroy(struct rvu *rvu)int rvu_cgx_init (struct rvu *rvu) {int cgx, err; +void *cgxd;/* CGX port id starts from 0 and are not necessarily contiguous * Hence we allocate resources based on the maximum port id value.
@@ -291,6 +294,23 @@ int rvu_cgx_init(struct rvu *rvu)if (err)return err; +/* Ensure event handler registration is completed, before +* we turn on the links +*/ +mb (); + +/* Do link up for all CGX ports */ +for (cgx =0 ; cgx <= rvu->cgx_cnt_max; cgx++) { + cgxd =rvu_cgx_pdata (cgx, rvu); +if (!cgxd) +continue ; + err =cgx_lmac_linkup_start (cgxd); +if (err) +dev_err (rvu->dev, +"Link up process failed to start on cgx %d\n" , + cgx); + } +return 0 ; }
Signature · 1 line
2.19.1
Re: [PATCH net-next 4/4] octeontx2-af: Bringup CGX LMAC links by default
Quoted 7 lines · Linu Cherian
From: Linu Cherian <[email protected]>
- Added new CGX firmware interface API for sending link up/down commands
- Do link up for cgx lmac ports by default at the time of CGX driver probe.
Hi Linu
This is a complex driver which i don't understand...
By link up, do you mean the equivalent of 'ip link set up dev ethX'?
Andrew
Re: [EXT] Re: [PATCH net-next 4/4] octeontx2-af: Bringup CGX LMAC links by default
Quoted 11 lines · Andrew Lunn
External Email
External Email
----------------------------------------------------------------------
Quoted 5 lines · Linu Cherian
From: Linu Cherian <[email protected]>
- Added new CGX firmware interface API for sending link up/down commands
Quoted 8 lines
Quoted 2 lines
- Do link up for cgx lmac ports by default at the time of CGX driver probe.
Hi Linu
This is a complex driver which i don't understand...
By link up, do you mean the equivalent of 'ip link set up dev ethX'?
Not really. It is used to do the necessary LMAC port hardware configuration based on the connected PHYs and bringup the the PHY links.
Quoted 2 lines
Andrew
Signature · 1 line
Linu cherian
David Miller
maintainerFrom: Linu Cherian <[email protected]>
Date: Thu, 22 Nov 2018 17:18:33 +0530
Quoted 6 lines
From: Linu Cherian <[email protected]>
Patch 1: Code cleanup
Patch 2: Adds support for an unhandled hardware configuration Patch 3: Preparatory patch for enabling cgx lmac links Patch 4: Support for enabling cgx lmac links
Series applied.