sonic-buildimage/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c
Saikrishna Arcot 4f9569132f Update saibcm-modules to compile with 5.10 kernel
Update the build rules in saibcm-modules to use the 5.10 kernel instead
of searching for the 4.19 kernel. In addition, some code changes were
done to get it to compile. The main categories of such changes are as
follows:

* For /proc files, `struct file_operations` has been replaced with
`struct proc_ops`.
* Y2038 changes to use the new APIs, since `do_gettimeofday()` is no
longer available.
* Minor changes in how external kernel module symbols are read by
modpost.

Signed-off-by: Saikrishna Arcot <sarcot@microsoft.com>
2021-11-10 15:27:22 -08:00

182 lines
3.4 KiB
C

/*! \file ngknet_linux.c
*
* Utility routines for Linux kernel APIs abstraction.
*
*/
/*
* $Copyright: Copyright 2018-2021 Broadcom. All rights reserved.
* The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A copy of the GNU General Public License version 2 (GPLv2) can
* be found in the LICENSES folder.$
*/
#include <linux/kconfig.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include "ngknet_linux.h"
/*!
* Time
*/
unsigned long
sal_time_usecs(void)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
struct timeval tv;
kal_time_val_get(&tv);
return tv.tv_sec * 1000000 + tv.tv_usec;
#else
struct timespec64 tv;
kal_time_val_get(&tv);
return tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
#endif
}
void
sal_usleep(unsigned long usec)
{
unsigned long then, now, hz;
hz = usec * HZ / 1000000;
if (hz) {
schedule_timeout(hz);
}
usec = usec * HZ % 1000000 / HZ;
if (usec) {
then = sal_time_usecs();
do {
schedule();
now = sal_time_usecs();
} while (now > then && (now - then) < usec);
}
}
/*!
* Synchronization
*/
typedef struct {
struct semaphore sem;
char *desc;
int binary;
} sem_ctrl_t;
sal_sem_t
sal_sem_create(char *desc, int binary, int count)
{
sem_ctrl_t *sc = kmalloc(sizeof(*sc), GFP_KERNEL);
if (sc != NULL) {
sema_init(&sc->sem, count);
sc->desc = desc;
sc->binary = binary;
}
return (sal_sem_t)sc;
}
void
sal_sem_destroy(sal_sem_t sem)
{
sem_ctrl_t *sc = (sem_ctrl_t *)sem;
kfree(sc);
}
int
sal_sem_take(sal_sem_t sem, int usec)
{
sem_ctrl_t *sc = (sem_ctrl_t *)sem;
int rv;
if (usec == SAL_SEM_FOREVER) {
do {
rv = down_interruptible(&sc->sem);
} while (rv == -EINTR);
return rv ? -1 : 0;
}
return -1;
}
int
sal_sem_give(sal_sem_t sem)
{
sem_ctrl_t *sc = (sem_ctrl_t *)sem;
up(&sc->sem);
return 0;
}
typedef struct spinlock_ctrl_s {
spinlock_t spinlock;
unsigned long flags;
char *desc;
} *spinlock_ctrl_t;
sal_spinlock_t
sal_spinlock_create(char *desc)
{
spinlock_ctrl_t sl = kmalloc(sizeof(*sl), GFP_KERNEL);
if (sl != NULL) {
spin_lock_init(&sl->spinlock);
sl->flags = 0;
sl->desc = desc;
}
return (sal_spinlock_t)sl;
}
void
sal_spinlock_destroy(sal_spinlock_t lock)
{
spinlock_ctrl_t sl = (spinlock_ctrl_t)lock;
kfree(sl);
}
int
sal_spinlock_lock(sal_spinlock_t lock)
{
spinlock_ctrl_t sl = (spinlock_ctrl_t)lock;
spin_lock_irqsave(&sl->spinlock, sl->flags);
return 0;
}
int
sal_spinlock_unlock(sal_spinlock_t lock)
{
spinlock_ctrl_t sl = (spinlock_ctrl_t)lock;
spin_unlock_irqrestore(&sl->spinlock, sl->flags);
return 0;
}