2929#include <linux/delay.h>
3030#include <linux/dmi.h>
3131#include <linux/kobject.h>
32+ #include "pddf_multifpgapci_defs.h"
3233#include "pddf_xcvr_defs.h"
3334
3435/*#define SFP_DEBUG*/
@@ -293,6 +294,81 @@ int xcvr_fpgapci_write(XCVR_ATTR *info, uint32_t val)
293294 return status ;
294295}
295296
297+ int xcvr_multifpgapci_read (XCVR_ATTR * info , int * output )
298+ {
299+ int status = 0 ;
300+ uint32_t offset = 0 ;
301+ struct pci_dev * pci_dev = NULL ;
302+
303+ if (ptr_multifpgapci_readpci == NULL ) {
304+ printk (KERN_ERR "PDDF_XCVR: Doesn't support MULTIFPGAPCI read yet" );
305+ status = -1 ;
306+ goto ret ;
307+ }
308+
309+ pci_dev = (struct pci_dev * )get_device_table (info -> devname );
310+ if (pci_dev == NULL ) {
311+ printk (KERN_ERR "PDDF_XCVR: Unable to get pci_dev of %s for %s\n" , info -> devname , info -> aname );
312+ status = -1 ;
313+ goto ret ;
314+ }
315+
316+ offset = info -> devaddr + info -> offset ;
317+ status = ptr_multifpgapci_readpci (pci_dev , offset , output );
318+
319+ ret :
320+ if (status )
321+ printk (KERN_ERR "%s: Error status = %d" , __FUNCTION__ , status );
322+
323+ return status ;
324+ }
325+
326+ int xcvr_multifpgapci_write (XCVR_ATTR * info , uint32_t val )
327+ {
328+ int status = 0 ;
329+ uint32_t reg , val_mask = 0 , dnd_value = 0 , reg_val ;
330+ uint32_t offset = 0 ;
331+ struct pci_dev * pci_dev = NULL ;
332+
333+ if (ptr_multifpgapci_readpci == NULL || ptr_multifpgapci_writepci == NULL ) {
334+ printk (KERN_ERR
335+ "PDDF_XCVR: Doesn't support MULTIFPGAPCI read or write yet" );
336+ return (-1 );
337+ }
338+
339+ pci_dev = (struct pci_dev * )get_device_table (info -> devname );
340+ if (pci_dev == NULL ) {
341+ printk (KERN_ERR "PDDF_XCVR: Unable to get pci_dev of %s for %s\n" , info -> devname , info -> aname );
342+ status = -1 ;
343+ goto ret ;
344+ }
345+
346+ offset = info -> devaddr + info -> offset ;
347+ val_mask = BIT_INDEX (info -> mask );
348+ status = ptr_multifpgapci_readpci (pci_dev , offset , & reg_val );
349+ if (status )
350+ goto ret ;
351+ dnd_value = reg_val & ~val_mask ;
352+
353+ // We expect val to be either 0 or 1. This function doesn't write val thru to the FPGA.
354+ // Instead it uses val and a mask to toggle bits.
355+ if (((val == 1 ) && (info -> cmpval != 0 )) || ((val == 0 ) && (info -> cmpval == 0 ))) {
356+ reg = dnd_value | val_mask ;
357+ } else {
358+ reg = dnd_value ;
359+ }
360+
361+ status = ptr_multifpgapci_writepci (pci_dev , reg , offset );
362+ if (status )
363+ goto ret ;
364+
365+ ret :
366+ if (status )
367+ printk (KERN_ERR "%s: Error status = %d" , __FUNCTION__ , status );
368+
369+ return status ;
370+ }
371+
296372int sonic_i2c_get_mod_pres (struct i2c_client * client , XCVR_ATTR * info , struct xcvr_data * data )
297373{
298374 int status = 0 ;
@@ -322,19 +398,31 @@ int sonic_i2c_get_mod_pres(struct i2c_client *client, XCVR_ATTR *info, struct xc
322398 sfp_dbg (KERN_INFO "\nMod presence :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , status , info -> devaddr , info -> mask , info -> offset );
323399 }
324400 }
325- else if ( strcmp (info -> devtype , "fpgapci" ) == 0 )
401+ else if (strcmp (info -> devtype , "fpgapci" ) == 0 )
326402 {
327403 status = xcvr_fpgapci_read (info );
328404
329405 if (status < 0 )
406+ {
330407 return status ;
408+ }
331409 else
332410 {
333411 modpres = ((status & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
334412 sfp_dbg (KERN_INFO "\nMod presence :0x%x, status= 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , status , info -> devaddr , info -> mask , info -> offset );
335413 }
336414 }
415+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
416+ {
417+ int output ;
337418
419+ status = xcvr_multifpgapci_read (info , & output );
420+ if (status )
421+ return status ;
422+
423+ modpres = ((output & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
424+ sfp_dbg (KERN_INFO "\nMod presence :0x%x, reg_value=0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , output , info -> devaddr , info -> mask , info -> offset );
425+ }
338426 else if (strcmp (info -> devtype , "eeprom" ) == 0 )
339427 {
340428 /* get client client for eeprom - Not Applicable */
@@ -372,18 +460,31 @@ int sonic_i2c_get_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct x
372460 sfp_dbg (KERN_INFO "\nMod reset :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , status , info -> devaddr , info -> mask , info -> offset );
373461 }
374462 }
375- else if ( strcmp (info -> devtype , "fpgapci" ) == 0 )
463+ else if (strcmp (info -> devtype , "fpgapci" ) == 0 )
376464 {
377465 status = xcvr_fpgapci_read (info );
378466 sfp_dbg (KERN_INFO "\n[%s] status=%x\n" , __FUNCTION__ , status );
379467 if (status < 0 )
468+ {
380469 return status ;
470+ }
381471 else
382472 {
383473 modreset = ((status & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
384474 sfp_dbg (KERN_INFO "\nMod reset :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modreset , status , info -> devaddr , info -> mask , info -> offset );
385475 }
386476 }
477+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
478+ {
479+ int output ;
480+
481+ status = xcvr_multifpgapci_read (info , & output );
482+ if (status )
483+ return status ;
484+
485+ modreset = ((output & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
486+ sfp_dbg (KERN_INFO "\nMod reset :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modreset , output , info -> devaddr , info -> mask , info -> offset );
487+ }
387488 else if (strcmp (info -> devtype , "eeprom" ) == 0 )
388489 {
389490 /* get client client for eeprom - Not Applicable */
@@ -421,19 +522,32 @@ int sonic_i2c_get_mod_intr_status(struct i2c_client *client, XCVR_ATTR *info, st
421522 sfp_dbg (KERN_INFO "\nModule Interrupt :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , status , info -> devaddr , info -> mask , info -> offset );
422523 }
423524 }
424- else if ( strcmp (info -> devtype , "fpgapci" ) == 0 )
525+ else if (strcmp (info -> devtype , "fpgapci" ) == 0 )
425526 {
426527 status = xcvr_fpgapci_read (info );
427528 sfp_dbg (KERN_INFO "\n[%s] status=%x\n" , __FUNCTION__ , status );
428529 if (status < 0 )
530+ {
429531 return status ;
532+ }
430533 else
431534 {
432535 mod_intr = ((status & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
433536 sfp_dbg (KERN_INFO "\nModule Interrupt :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , mod_intr , status , info -> devaddr , info -> mask , info -> offset );
434537 }
435538 }
539+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
540+ {
541+ int output ;
436542
543+ status = xcvr_multifpgapci_read (info , & output );
544+ if (status ) {
545+ return status ;
546+ }
547+
548+ mod_intr = ((output & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
549+ sfp_dbg (KERN_INFO "\nModule Interrupt :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , mod_intr , output , info -> devaddr , info -> mask , info -> offset );
550+ }
437551 else if (strcmp (info -> devtype , "eeprom" ) == 0 )
438552 {
439553 /* get client client for eeprom - Not Applicable */
@@ -472,18 +586,31 @@ int sonic_i2c_get_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct
472586 sfp_dbg (KERN_INFO "\nModule LPmode :0x%x, reg_value = 0x%x, devaddr=0x%x, mask=0x%x, offset=0x%x\n" , modpres , status , info -> devaddr , info -> mask , info -> offset );
473587 }
474588 }
475- else if ( strcmp (info -> devtype , "fpgapci" ) == 0 )
589+ else if (strcmp (info -> devtype , "fpgapci" ) == 0 )
476590 {
477591 status = xcvr_fpgapci_read (info );
478592 sfp_dbg (KERN_INFO "\n[%s] status=%x\n" , __FUNCTION__ , status );
479593 if (status < 0 )
594+ {
480595 return status ;
596+ }
481597 else
482598 {
483599 lpmode = ((status & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
484600 sfp_dbg (KERN_INFO "\nlpmode :0x%x, reg_val = 0x%x, op=0x%x, mask=0x%x, offset=0x%x\n" , lpmode , status , status & BIT_INDEX (info -> mask ), info -> mask , info -> offset );
485601 }
486602 }
603+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
604+ {
605+ int output ;
606+
607+ status = xcvr_multifpgapci_read (info , & output );
608+ if (status )
609+ return status ;
610+
611+ lpmode = ((output & BIT_INDEX (info -> mask )) == info -> cmpval ) ? 1 : 0 ;
612+ sfp_dbg (KERN_INFO "\nlpmode :0x%x, reg_val = 0x%x, op=0x%x, mask=0x%x, offset=0x%x\n" , lpmode , output , status & BIT_INDEX (info -> mask ), info -> mask , info -> offset );
613+ }
487614 else if (strcmp (info -> devtype , "eeprom" ) == 0 )
488615 {
489616 /* get client client for eeprom - Not Applicable */
@@ -610,12 +737,19 @@ int sonic_i2c_set_mod_reset(struct i2c_client *client, XCVR_ATTR *info, struct x
610737 {
611738 status = xcvr_fpgapci_write (info , data -> reset );
612739 }
740+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
741+ {
742+ status = xcvr_multifpgapci_write (info , data -> reset );
743+ }
613744 else
614745 {
615746 printk (KERN_ERR "Error: Invalid device type (%s) to set xcvr reset\n" , info -> devtype );
616747 status = -1 ;
617748 }
618749
750+ if (status < 0 )
751+ printk (KERN_ERR "%s: Error status = %d" , __FUNCTION__ , status );
752+
619753 return status ;
620754}
621755
@@ -635,6 +769,10 @@ int sonic_i2c_set_mod_lpmode(struct i2c_client *client, XCVR_ATTR *info, struct
635769 {
636770 status = xcvr_fpgapci_write (info , data -> lpmode );
637771 }
772+ else if (strcmp (info -> devtype , "multifpgapci" ) == 0 )
773+ {
774+ status = xcvr_multifpgapci_write (info , data -> lpmode );
775+ }
638776 else
639777 {
640778 printk (KERN_ERR "Error: Invalid device type (%s) to set xcvr lpmode\n" , info -> devtype );
0 commit comments